From b4f31bd6cd3cdd132c333a5899b8d9326422c52b Mon Sep 17 00:00:00 2001 From: Sihyung Woo <75494566+sihyung-maxim@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:25:36 -0500 Subject: [PATCH] feat(Examples): Add generic I2C RX/TX DMA vector flexibility to I2C examples for all parts (#693) Co-authored-by: sihyung-maxim Co-authored-by: Jake Carter --- Examples/MAX32572/I2C/README.md | 6 +- Examples/MAX32572/I2C/main.c | 112 +++-- Examples/MAX32650/I2C/README.md | 9 +- Examples/MAX32650/I2C/main.c | 84 ++-- Examples/MAX32655/I2C/README.md | 6 +- Examples/MAX32655/I2C/main.c | 88 ++-- Examples/MAX32660/I2C/README.md | 4 +- Examples/MAX32660/I2C/main.c | 81 ++-- Examples/MAX32662/I2C/README.md | 2 + Examples/MAX32662/I2C/main.c | 87 ++-- Examples/MAX32665/I2C/README.md | 9 +- Examples/MAX32665/I2C/main.c | 93 ++-- Examples/MAX32670/I2C/README.md | 6 +- Examples/MAX32670/I2C/main.c | 87 +++- Examples/MAX32672/I2C/README.md | 6 +- Examples/MAX32672/I2C/main.c | 86 +++- Examples/MAX32675/I2C/README.md | 4 +- Examples/MAX32675/I2C/main.c | 93 ++-- Examples/MAX32680/I2C/README.md | 6 +- Examples/MAX32680/I2C/main.c | 81 +++- Examples/MAX32690/I2C/README.md | 6 +- Examples/MAX32690/I2C/main.c | 75 ++- Examples/MAX78002/I2C/README.md | 6 +- Examples/MAX78002/I2C/main.c | 80 ++- .../PeriphDrivers/Include/MAX32520/i2c.h | 90 +++- .../PeriphDrivers/Include/MAX32570/i2c.h | 60 ++- .../PeriphDrivers/Include/MAX32572/i2c.h | 60 ++- .../PeriphDrivers/Include/MAX32650/i2c.h | 58 ++- .../PeriphDrivers/Include/MAX32655/i2c.h | 67 ++- .../PeriphDrivers/Include/MAX32660/i2c.h | 60 ++- .../PeriphDrivers/Include/MAX32662/i2c.h | 67 ++- .../PeriphDrivers/Include/MAX32665/dma.h | 2 + .../PeriphDrivers/Include/MAX32665/i2c.h | 50 ++ .../PeriphDrivers/Include/MAX32670/i2c.h | 70 ++- .../PeriphDrivers/Include/MAX32672/i2c.h | 60 ++- .../PeriphDrivers/Include/MAX32675/i2c.h | 60 ++- .../PeriphDrivers/Include/MAX32680/i2c.h | 67 ++- .../PeriphDrivers/Include/MAX32690/i2c.h | 67 ++- .../PeriphDrivers/Include/MAX78000/i2c.h | 61 ++- .../PeriphDrivers/Include/MAX78002/i2c.h | 63 ++- Libraries/PeriphDrivers/Source/I2C/i2c_ai87.c | 110 +++-- Libraries/PeriphDrivers/Source/I2C/i2c_es17.c | 84 +++- Libraries/PeriphDrivers/Source/I2C/i2c_me10.c | 102 ++-- Libraries/PeriphDrivers/Source/I2C/i2c_me11.c | 100 ++-- Libraries/PeriphDrivers/Source/I2C/i2c_me12.c | 102 ++-- Libraries/PeriphDrivers/Source/I2C/i2c_me13.c | 107 ++-- Libraries/PeriphDrivers/Source/I2C/i2c_me14.c | 118 +++-- Libraries/PeriphDrivers/Source/I2C/i2c_me15.c | 121 +++-- Libraries/PeriphDrivers/Source/I2C/i2c_me16.c | 406 ---------------- Libraries/PeriphDrivers/Source/I2C/i2c_me17.c | 124 +++-- Libraries/PeriphDrivers/Source/I2C/i2c_me18.c | 110 +++-- Libraries/PeriphDrivers/Source/I2C/i2c_me21.c | 110 +++-- Libraries/PeriphDrivers/Source/I2C/i2c_me55.c | 99 ++-- Libraries/PeriphDrivers/Source/I2C/i2c_reva.c | 314 +++++++++--- Libraries/PeriphDrivers/Source/I2C/i2c_reva.h | 9 +- Libraries/PeriphDrivers/Source/I2C/i2c_revb.c | 456 ++++++++++++++++++ Libraries/PeriphDrivers/Source/I2C/i2c_revb.h | 168 +++++++ 57 files changed, 3360 insertions(+), 1359 deletions(-) delete mode 100644 Libraries/PeriphDrivers/Source/I2C/i2c_me16.c create mode 100644 Libraries/PeriphDrivers/Source/I2C/i2c_revb.c create mode 100644 Libraries/PeriphDrivers/Source/I2C/i2c_revb.h diff --git a/Examples/MAX32572/I2C/README.md b/Examples/MAX32572/I2C/README.md index 8ec191b567..ff6ccb592a 100644 --- a/Examples/MAX32572/I2C/README.md +++ b/Examples/MAX32572/I2C/README.md @@ -22,7 +22,7 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -37,9 +37,9 @@ P2.19 to P0.7 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32572/I2C/main.c b/Examples/MAX32572/I2C/main.c index 014af8e224..7f904c2cde 100644 --- a/Examples/MAX32572/I2C/main.c +++ b/Examples/MAX32572/I2C/main.c @@ -33,10 +33,10 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. For - * this example you must connect P0.6 to P0.14 (SDA) and P0.7 to P0.15 (SCL). The Master - * will use P0.6 and P0.7. The Slave will use P0.14 and P0.15. You must also + * this example you must connect P0.6 to P0.18 (SDA) and P0.7 to P0.19 (SCL). The Master + * will use P0.6 and P0.7. The Slave will use P0.18 and P0.19. You must also * connect the pull-up jumpers (JP23 and JP24) to the proper I/O voltage. * Refer to JP27 to determine the I/O voltage. * @note Other devices on the EvKit will be using the same bus. This example cannot be combined with @@ -44,14 +44,21 @@ */ /***** Includes *****/ + #include #include #include - -#include +#include "mxc_device.h" +#include "mxc_delay.h" +#include "mxc_errors.h" +#include "nvic_table.h" +#include "i2c.h" +#include "dma.h" +#include "led.h" /***** Definitions *****/ -// #define MASTERDMA + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C1 #define I2C_SLAVE MXC_I2C2 @@ -60,14 +67,14 @@ #define I2C_SLAVE_ADDR (0x51) #define I2C_BYTES 255 -typedef enum { FAILED, PASSED } test_t; - /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; @@ -79,28 +86,22 @@ volatile int rxnum = 0; void I2C2_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; } -void DMA0_IRQHandler(void) +void DMA_TX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(0); - DMA_FLAG = 1; } -void DMA1_IRQHandler(void) +void DMA_RX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(1); - DMA_FLAG = 1; } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -113,28 +114,23 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = i; - } - txnum = I2C_BYTES; txcnt = 0; - i2c->int_fl0 = MXC_F_I2C_INT_FL0_TX_LOCK_OUT | MXC_F_I2C_INT_FL0_ADDR_MATCH; + i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; break; case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); if (rxnum == I2C_BYTES) { - i2c->int_en0 |= MXC_F_I2C_INT_EN0_ADDR_MATCH; + i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } + break; case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -149,10 +145,11 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); - printf("i2c->int_fl0 = 0x%08x\n", i2c->int_fl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -167,6 +164,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -185,7 +183,7 @@ void printData(void) } //Compare data to see if they are the same -int verifyData() +int verifyData(void) { int i, fails = 0; @@ -196,16 +194,16 @@ int verifyData() } if (fails > 0) { - return FAILED; - } else { - return PASSED; + return E_FAIL; } + + return E_NO_ERROR; } // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -216,18 +214,27 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); - if (error != E_NO_ERROR) { printf("Failed master\n"); return FAILED; } + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); + return error; + } else { + printf("\n-->I2C Master Initialization Complete"); + } + //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); - if (error != E_NO_ERROR) { printf("Failed slave\n"); return FAILED; + } else { + printf("\n-->I2C Slave Initialization Complete"); } NVIC_SetVector(I2C2_IRQn, I2C2_IRQHandler); @@ -242,6 +249,8 @@ int main() for (i = 0; i < I2C_BYTES; i++) { txdata[i] = i; rxdata[i] = 0; + Stxdata[i] = i; + Srxdata[i] = 0; } // This will write data to slave @@ -264,43 +273,42 @@ int main() return FAILED; } - MXC_DMA_ReleaseChannel(0); - MXC_DMA_ReleaseChannel(1); - #ifdef MASTERDMA - NVIC_EnableIRQ(DMA0_IRQn); - NVIC_EnableIRQ(DMA1_IRQn); - __enable_irq(); + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { printf("Error writing: %d\n", error); - return FAILED; + return error; } - - while (DMA_FLAG == 0) {} - #else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); - return FAILED; + return error; } +#endif while (I2C_FLAG == 1) {} -#endif - printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData()) { printf("\n-->I2C Transaction Successful\n"); - LED_On(0); - return 0; } else { printf("\n-->I2C Transaction Failed\n"); - return -1; + return E_FAIL; } + + return E_NO_ERROR; } diff --git a/Examples/MAX32650/I2C/README.md b/Examples/MAX32650/I2C/README.md index e911c74ee0..fc6b43a111 100644 --- a/Examples/MAX32650/I2C/README.md +++ b/Examples/MAX32650/I2C/README.md @@ -21,13 +21,16 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -***** I2C Loopback Example ***** -This example uses one I2C peripheral as a master -to read and write to another I2C which acts as a slave. +******** I2C Master-Slave Transaction Demo ********* + +This example uses one I2C peripheral as a master to +read and write to another I2C which acts as a slave. You will need to connect P2.7 to P2.17 (SDA) and P2.8 to P2.18 (SCL). +-->I2C Master Initialization Complete +-->I2C Slave Initialization Complete -->Writing data to slave, and reading the data back diff --git a/Examples/MAX32650/I2C/main.c b/Examples/MAX32650/I2C/main.c index ab2f02d5e6..5fdfef5c64 100644 --- a/Examples/MAX32650/I2C/main.c +++ b/Examples/MAX32650/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,6 +45,7 @@ */ /***** Includes *****/ + #include #include #include @@ -55,7 +56,8 @@ #include "dma.h" /***** Definitions *****/ -// #define MASTERDMA + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C0 #define I2C_SLAVE MXC_I2C1 @@ -65,11 +67,13 @@ #define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; @@ -81,28 +85,22 @@ volatile int rxnum = 0; void I2C1_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; } -void DMA0_IRQHandler(void) +void DMA_TX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(0); - DMA_FLAG = 1; } -void DMA1_IRQHandler(void) +void DMA_RX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(1); - DMA_FLAG = 1; } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -113,19 +111,23 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) // Clear bytes written rxnum = 0; break; + case MXC_I2C_EVT_MASTER_RD: // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } txnum = I2C_BYTES; txcnt = 0; i2c->int_fl0 = MXC_F_I2C_INT_FL0_TXLOI | MXC_F_I2C_INT_FL0_AMI; break; + case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); + if (rxnum == I2C_BYTES) { + i2c->int_en0 |= MXC_F_I2C_INT_EN0_AMIE; + } + break; + case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: // Write as much data as possible into TX FIFO @@ -133,23 +135,27 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (txcnt >= txnum) { break; } + int num = MXC_I2C_GetTXFIFOAvailable(i2c); num = (num > (txnum - txcnt)) ? (txnum - txcnt) : num; txcnt += MXC_I2C_WriteTXFIFO(i2c, &Stxdata[txcnt], num); break; + default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->int_fl0 = 0x%08x\n", i2c->int_fl0); - printf("i2c->status = 0x%08x\n", i2c->stat); + printf("i2c->stat = 0x%08x\n", i2c->stat); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); return 1; } } + return 0; } @@ -157,12 +163,15 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); + for (i = 0; i < sizeof(txdata); ++i) { printf("%02x ", txdata[i]); } printf("\n\n-->RxData: "); + for (i = 0; i < sizeof(rxdata); ++i) { printf("%02x ", rxdata[i]); } @@ -176,6 +185,7 @@ void printData(void) int verifyData(void) { int i, fails = 0; + for (i = 0; i < I2C_BYTES; ++i) { if (txdata[i] != rxdata[i]) { ++fails; @@ -192,9 +202,10 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n***** I2C Loopback Example *****\n"); - printf("This example uses one I2C peripheral as a master\n"); - printf("to read and write to another I2C which acts as a slave.\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); + printf("\nThis example uses one I2C peripheral as a master to\n"); + printf("read and write to another I2C which acts as a slave.\n"); + printf("\nYou will need to connect P2.7 to P2.17 (SDA) and\n"); printf("P2.8 to P2.18 (SCL).\n"); @@ -203,17 +214,30 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { - printf("Failed to initialize master.\n"); + printf("Failed master.\n"); + return error; + } + +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); return error; } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); if (error != E_NO_ERROR) { - printf("Failed to initialize slave.\n"); + printf("Failed slave\n"); return error; } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C1_IRQn, I2C1_IRQHandler); NVIC_EnableIRQ(I2C1_IRQn); __enable_irq(); @@ -226,6 +250,8 @@ int main() for (i = 0; i < I2C_BYTES; i++) { txdata[i] = i; rxdata[i] = 0; + Stxdata[i] = i; + Srxdata[i] = 0; } // This will write data to slave @@ -249,31 +275,35 @@ int main() } #ifdef MASTERDMA - MXC_DMA_ReleaseChannel(0); - MXC_DMA_ReleaseChannel(1); + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); - NVIC_EnableIRQ(DMA0_IRQn); - NVIC_EnableIRQ(DMA1_IRQn); - __enable_irq(); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } - while (DMA_FLAG == 0) {} #else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} -#endif printf("\n-->Result: \n"); printData(); printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32655/I2C/README.md b/Examples/MAX32655/I2C/README.md index 8fd647fe1d..0732ea4322 100644 --- a/Examples/MAX32655/I2C/README.md +++ b/Examples/MAX32655/I2C/README.md @@ -31,7 +31,7 @@ If using the MAX32655EVKIT (EvKit_V1): The Console UART of the device will output these messages: ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -46,9 +46,9 @@ P0.11 to P0.17 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32655/I2C/main.c b/Examples/MAX32655/I2C/main.c index 13e1424e0f..12225190d4 100644 --- a/Examples/MAX32655/I2C/main.c +++ b/Examples/MAX32655/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. For * this example you must connect P0.10 to P0.16 (SCL) and P0.11 to P0.17 (SDA). The Master * will use P0.10 and P0.11. The Slave will use P0.16 and P0.17. You must also @@ -41,6 +41,7 @@ */ /***** Includes *****/ + #include #include #include @@ -51,38 +52,51 @@ #include "dma.h" /***** Definitions *****/ + +#define MASTERDMA //Comment this line out if standard I2C transaction is required + #define I2C_MASTER MXC_I2C1 #define I2C_SLAVE MXC_I2C0 #define I2C_FREQ 100000 #define I2C_SLAVE_ADDR (0x51) -#define I2C_BYTES 100 +#define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; volatile int rxnum = 0; -volatile int num; + /***** Functions *****/ //Slave interrupt handler void I2C0_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; +} + +void DMA_TX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + +void DMA_RX_IRQHandler(void) +{ + MXC_DMA_Handler(); } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -95,12 +109,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } - txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; @@ -109,7 +118,6 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); - if (rxnum == I2C_BYTES) { i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } @@ -118,7 +126,6 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -133,10 +140,11 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); - printf("i2c->int_fl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -151,6 +159,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -189,7 +198,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -200,26 +209,34 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); + if (error != E_NO_ERROR) { + printf("Failed master\n"); + return error; + } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); if (error != E_NO_ERROR) { - printf("-->Failed master\n"); - return E_FAIL; - } else { - printf("\n-->I2C Master Initialization Complete"); + printf("Failed DMA master\n"); + return error; } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); - if (error != E_NO_ERROR) { printf("Failed slave\n"); - return E_FAIL; - } else { - printf("\n-->I2C Slave Initialization Complete"); + return error; } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C0_IRQn, I2C0_IRQHandler); NVIC_EnableIRQ(I2C0_IRQn); + __enable_irq(); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); @@ -253,19 +270,36 @@ int main() return E_FAIL; } +#ifdef MASTERDMA + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); + + if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { + printf("Error writing: %d\n", error); + return error; + } +#else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); - return E_FAIL; + return error; } +#endif while (I2C_FLAG == 1) {} printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32660/I2C/README.md b/Examples/MAX32660/I2C/README.md index 91aafc8966..2c0de0dbe8 100644 --- a/Examples/MAX32660/I2C/README.md +++ b/Examples/MAX32660/I2C/README.md @@ -21,7 +21,7 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -29,6 +29,8 @@ read and write to another I2C which acts as a slave. You will need to connect P0.8->P0.2 (SCL) and P0.9->P0.3 (SDA). +-->I2C Master Initialization Complete +-->I2C Slave Initialization Complete -->Writing data to slave, and reading the data back diff --git a/Examples/MAX32660/I2C/main.c b/Examples/MAX32660/I2C/main.c index 8733f66060..1700b564e6 100644 --- a/Examples/MAX32660/I2C/main.c +++ b/Examples/MAX32660/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,6 +45,7 @@ */ /***** Includes *****/ + #include #include #include @@ -56,7 +57,8 @@ #include "dma.h" /***** Definitions *****/ -// #define MASTERDMA //Comment this line out if standard I2C transaction is required + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C0 #define I2C_SLAVE MXC_I2C1 @@ -66,11 +68,13 @@ #define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; @@ -82,28 +86,22 @@ volatile int rxnum = 0; void I2C1_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; } -void DMA0_IRQHandler(void) +void DMA_TX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(0); - DMA_FLAG = 1; } -void DMA1_IRQHandler(void) +void DMA_RX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(1); - DMA_FLAG = 1; } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -114,22 +112,23 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) // Clear bytes written rxnum = 0; break; + case MXC_I2C_EVT_MASTER_RD: - // Echo data from Srxdata buffer - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } + // Serve as a 16 byte loopback, returning data*2 txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TXLOI | MXC_F_I2C_INTFL0_AMI; break; + case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); if (rxnum == I2C_BYTES) { i2c->inten0 |= MXC_F_I2C_INTEN0_AMIE; } + break; + case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: // Write as much data as possible into TX FIFO @@ -137,23 +136,27 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (txcnt >= txnum) { break; } + int num = MXC_I2C_GetTXFIFOAvailable(i2c); num = (num > (txnum - txcnt)) ? (txnum - txcnt) : num; txcnt += MXC_I2C_WriteTXFIFO(i2c, &Stxdata[txcnt], num); break; + default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); return 1; } } + return 0; } @@ -161,12 +164,15 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); + for (i = 0; i < sizeof(txdata); ++i) { printf("%02x ", txdata[i]); } printf("\n\n-->RxData: "); + for (i = 0; i < sizeof(rxdata); ++i) { printf("%02x ", rxdata[i]); } @@ -180,11 +186,13 @@ void printData(void) int verifyData(void) { int i, fails = 0; + for (i = 0; i < I2C_BYTES; ++i) { if (txdata[i] != rxdata[i]) { ++fails; } } + if (fails > 0) { return E_FAIL; } @@ -195,7 +203,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -207,9 +215,20 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { - printf("Failed master\n"); + printf("Failed master.\n"); + return error; + } + +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); return error; } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); @@ -218,6 +237,8 @@ int main() return error; } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C1_IRQn, I2C1_IRQHandler); NVIC_EnableIRQ(I2C1_IRQn); __enable_irq(); @@ -229,7 +250,9 @@ int main() // Initialize test data for (i = 0; i < I2C_BYTES; i++) { txdata[i] = i; - rxdata[i] = 0xFF; + rxdata[i] = 0; + Stxdata[i] = i; + Srxdata[i] = 0; } // This will write data to slave @@ -253,31 +276,35 @@ int main() } #ifdef MASTERDMA - MXC_DMA_ReleaseChannel(0); - MXC_DMA_ReleaseChannel(1); + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); - NVIC_EnableIRQ(DMA0_IRQn); - NVIC_EnableIRQ(DMA1_IRQn); - __enable_irq(); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { printf("Error writing: %d\n", error); - return FAILED; + return error; } - while (DMA_FLAG == 0) {} #else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} -#endif printf("\n-->Result: \n"); printData(); printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32662/I2C/README.md b/Examples/MAX32662/I2C/README.md index b34e22c7e6..b72a594976 100644 --- a/Examples/MAX32662/I2C/README.md +++ b/Examples/MAX32662/I2C/README.md @@ -31,6 +31,8 @@ You will need to connect P0.12->P0.6 (SCL) and P0.13->P0.9 (SDA). As well jumper JP1 (VREF) needs to be removed. +-->I2C Master Initialization Complete +-->I2C Slave Initialization Complete -->Writing data to slave, and reading the data back diff --git a/Examples/MAX32662/I2C/main.c b/Examples/MAX32662/I2C/main.c index f413370849..fae45a3f72 100644 --- a/Examples/MAX32662/I2C/main.c +++ b/Examples/MAX32662/I2C/main.c @@ -33,10 +33,10 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. For - * this example you must connect P0.12 to P0.18 (SCL) and P0.13 to P0.19 (SCL). The Master - * will use P0.12 and P0.13. The Slave will use P0.18 and P0.19. You must also + * this example you must connect P0.12 to P0.6 (SCL) and P0.13 to P0.9 (SCL). The Master + * will use P0.12 and P0.13. The Slave will use P0.6 and P0.9. You must also * connect the pull-up jumpers (JP23 and JP24) to the proper I/O voltage. * Refer to JP27 to determine the I/O voltage. * @note Other devices on the EvKit will be using the same bus. This example cannot be combined with @@ -44,6 +44,7 @@ */ /***** Includes *****/ + #include #include #include @@ -56,7 +57,8 @@ #include "board.h" /***** Definitions *****/ -//#define MASTERDMA //Comment this line out if standard I2C transaction is required + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C0 #define I2C_SLAVE MXC_I2C1 @@ -66,11 +68,13 @@ #define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; @@ -82,28 +86,22 @@ volatile int rxnum = 0; void I2C1_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; } -void DMA0_IRQHandler(void) +void DMA_TX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(0); - DMA_FLAG = 1; } -void DMA1_IRQHandler(void) +void DMA_RX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(1); - DMA_FLAG = 1; } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -114,22 +112,23 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) // Clear bytes written rxnum = 0; break; + case MXC_I2C_EVT_MASTER_RD: // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = i; - } txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; break; + case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); if (rxnum == I2C_BYTES) { i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } + break; + case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: // Write as much data as possible into TX FIFO @@ -137,23 +136,27 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (txcnt >= txnum) { break; } + int num = MXC_I2C_GetTXFIFOAvailable(i2c); num = (num > (txnum - txcnt)) ? (txnum - txcnt) : num; txcnt += MXC_I2C_WriteTXFIFO(i2c, &Stxdata[txcnt], num); break; + default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); return 1; } } + return 0; } @@ -161,12 +164,15 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); + for (i = 0; i < sizeof(txdata); ++i) { printf("%02x ", txdata[i]); } printf("\n\n-->RxData: "); + for (i = 0; i < sizeof(rxdata); ++i) { printf("%02x ", rxdata[i]); } @@ -180,22 +186,24 @@ void printData(void) int verifyData(void) { int i, fails = 0; + for (i = 0; i < I2C_BYTES; ++i) { if (txdata[i] != rxdata[i]) { ++fails; } } + if (fails > 0) { return E_FAIL; - } else { - return E_NO_ERROR; } + + return E_NO_ERROR; } // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -209,17 +217,28 @@ int main() printf("Either connect SLAVE_SCL to P0.12 and SLAVE_SDA to P0.13\n"); printf("Or use breadboard and connect P0.12 to 3.3V with 4.7k \n"); printf("and P0.13 to 3.3V with 4.7k\n"); - #endif + int error, i = 0; //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { - printf("Failed master\n"); + printf("Failed master.\n"); return error; } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); + return error; + } +#endif + + printf("\n-->I2C Master Initialization Complete"); + //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); if (error != E_NO_ERROR) { @@ -227,6 +246,8 @@ int main() return error; } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C1_IRQn, I2C1_IRQHandler); NVIC_EnableIRQ(I2C1_IRQn); __enable_irq(); @@ -239,6 +260,8 @@ int main() for (i = 0; i < I2C_BYTES; i++) { txdata[i] = i; rxdata[i] = 0; + Stxdata[i] = i; + Srxdata[i] = 0; } // This will write data to slave @@ -262,31 +285,35 @@ int main() } #ifdef MASTERDMA - MXC_DMA_ReleaseChannel(0); - MXC_DMA_ReleaseChannel(1); + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); - NVIC_EnableIRQ(DMA0_IRQn); - NVIC_EnableIRQ(DMA1_IRQn); - __enable_irq(); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { printf("Error writing: %d\n", error); - return FAILED; + return error; } - while (DMA_FLAG == 0) {} #else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} -#endif printf("\n-->Result: \n"); printData(); printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32665/I2C/README.md b/Examples/MAX32665/I2C/README.md index 526f5e9732..db6d800213 100644 --- a/Examples/MAX32665/I2C/README.md +++ b/Examples/MAX32665/I2C/README.md @@ -23,13 +23,16 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -***** I2C Loopback Example ***** -This example uses one I2C peripheral as a master -to read and write to another I2C which acts as a slave. +******** I2C Master-Slave Transaction Demo ********* + +This example uses one I2C peripheral as a master to +read and write to another I2C which acts as a slave. You will need to connect P0.6 (I2C0 SDA) to P0.14 (I2C1 SDA) and P0.7 (I2C0 SCL) to P0.15 (I2C1 SCL). +-->I2C Master Initialization Complete +-->I2C Slave Initialization Complete -->Writing data to slave, and reading the data back diff --git a/Examples/MAX32665/I2C/main.c b/Examples/MAX32665/I2C/main.c index 7eb9661218..37191c8697 100644 --- a/Examples/MAX32665/I2C/main.c +++ b/Examples/MAX32665/I2C/main.c @@ -45,6 +45,7 @@ */ /***** Includes *****/ + #include #include #include @@ -56,7 +57,8 @@ #include "board.h" /***** Definitions *****/ -// #define MASTERDMA + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C0_BUS0 #if defined(BOARD_FTHR2) @@ -72,10 +74,13 @@ #define I2C_BYTES 255 /***** Globals *****/ -static uint8_t Sdata[I2C_BYTES]; + +static uint8_t Stxdata[I2C_BYTES]; +static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA0_TX_CH; +int8_t DMA0_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; @@ -87,28 +92,22 @@ volatile int rxnum = 0; void I2C_Slave_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; } -void DMA0_IRQHandler(void) +void DMA0_TX_IRQHandler(void) { MXC_DMA_Handler(MXC_DMA0); - MXC_DMA_ReleaseChannel(0); - DMA_FLAG = 1; } -void DMA1_IRQHandler(void) +void DMA0_RX_IRQHandler(void) { MXC_DMA_Handler(MXC_DMA0); - MXC_DMA_ReleaseChannel(1); - DMA_FLAG = 1; } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -119,15 +118,23 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) // Clear bytes written rxnum = 0; break; + case MXC_I2C_EVT_MASTER_RD: + // Serve as a 16 byte loopback, returning data*2 txnum = I2C_BYTES; txcnt = 0; i2c->int_fl0 = MXC_F_I2C_INT_FL0_TX_LOCK_OUT | MXC_F_I2C_INT_FL0_ADDR_MATCH; break; + case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: - rxnum += MXC_I2C_ReadRXFIFO(i2c, &Sdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); + rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); + if (rxnum == I2C_BYTES) { + i2c->int_en0 |= MXC_F_I2C_INT_EN0_ADDR_MATCH; + } + break; + case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: // Write as much data as possible into TX FIFO @@ -135,10 +142,12 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (txcnt >= txnum) { break; } + int num = MXC_I2C_GetTXFIFOAvailable(i2c); num = (num > (txnum - txcnt)) ? (txnum - txcnt) : num; - txcnt += MXC_I2C_WriteTXFIFO(i2c, &Sdata[txcnt], num); + txcnt += MXC_I2C_WriteTXFIFO(i2c, &Stxdata[txcnt], num); break; + default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); @@ -146,12 +155,14 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { - rxnum += MXC_I2C_ReadRXFIFO(i2c, &Sdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); + rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); return 1; } } + return 0; } @@ -159,12 +170,15 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); + for (i = 0; i < sizeof(txdata); ++i) { printf("%02x ", txdata[i]); } printf("\n\n-->RxData: "); + for (i = 0; i < sizeof(rxdata); ++i) { printf("%02x ", rxdata[i]); } @@ -178,24 +192,26 @@ void printData(void) int verifyData(void) { int i, fails = 0; + for (i = 0; i < I2C_BYTES; ++i) { if (txdata[i] != rxdata[i]) { ++fails; } } + if (fails > 0) { return E_FAIL; - } else { - return E_NO_ERROR; } + + return E_NO_ERROR; } // ***************************************************************************** int main() { - printf("\n***** I2C Loopback Example *****\n"); - printf("This example uses one I2C peripheral as a master\n"); - printf("to read and write to another I2C which acts as a slave.\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); + printf("\nThis example uses one I2C peripheral as a master to\n"); + printf("read and write to another I2C which acts as a slave.\n"); #if defined(BOARD_FTHR2) printf("\nYou will need to connect P0.6 (I2C0 SDA) to P1.14 (I2C2 SDA) and\n"); printf("P0.7 (I2C0 SCL) to P1.15 (I2C2 SCL).\n"); @@ -209,17 +225,30 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { - printf("Failed to initialize master.\n"); + printf("Failed master\n"); return error; } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA0, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); + return error; + } +#endif + + printf("\n-->I2C Master Initialization Complete"); + //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); if (error != E_NO_ERROR) { - printf("Failed to initialize slave.\n"); + printf("Failed slave\n"); return error; } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C_SLAVE_IRQn, I2C_Slave_IRQHandler); NVIC_EnableIRQ(I2C_SLAVE_IRQn); __enable_irq(); @@ -232,6 +261,8 @@ int main() for (i = 0; i < I2C_BYTES; i++) { txdata[i] = i; rxdata[i] = 0; + Stxdata[i] = i; + Srxdata[i] = 0; } // This will write data to slave @@ -254,27 +285,29 @@ int main() return error; } - MXC_DMA_ReleaseChannel(0); - MXC_DMA_ReleaseChannel(1); - #ifdef MASTERDMA - NVIC_EnableIRQ(DMA0_IRQn); - NVIC_EnableIRQ(DMA1_IRQn); - __enable_irq(); + DMA0_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA0_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + //There are two DMA instances for the MAX32665 + NVIC_EnableIRQ(MXC_DMA0_CH_GET_IRQ(DMA0_TX_CH)); + NVIC_EnableIRQ(MXC_DMA0_CH_GET_IRQ(DMA0_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA0_CH_GET_IRQ(DMA0_TX_CH), DMA0_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA0_CH_GET_IRQ(DMA0_RX_CH), DMA0_RX_IRQHandler); if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster, MXC_DMA0)) != 0) { printf("Error writing: %d\n", error); - return FAILED; + return error; } - while (DMA_FLAG == 0) {} #else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} -#endif printf("\n-->Result: \n"); printData(); diff --git a/Examples/MAX32670/I2C/README.md b/Examples/MAX32670/I2C/README.md index 61d4077979..65ca351c59 100644 --- a/Examples/MAX32670/I2C/README.md +++ b/Examples/MAX32670/I2C/README.md @@ -22,7 +22,7 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -37,9 +37,9 @@ P0.13 to P0.7 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32670/I2C/main.c b/Examples/MAX32670/I2C/main.c index 45fd1e20db..688e50cd39 100644 --- a/Examples/MAX32670/I2C/main.c +++ b/Examples/MAX32670/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,50 +45,64 @@ */ /***** Includes *****/ + #include #include #include #include "mxc_device.h" #include "mxc_delay.h" +#include "mxc_errors.h" #include "nvic_table.h" #include "i2c.h" #include "dma.h" +#include "led.h" /***** Definitions *****/ -// #define MASTERDMA + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C1 #define I2C_SLAVE MXC_I2C0 #define I2C_FREQ 100000 #define I2C_SLAVE_ADDR (0x51) -#define I2C_BYTES 100 +#define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; volatile int rxnum = 0; -volatile int num; + /***** Functions *****/ //Slave interrupt handler void I2C0_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; +} + +void DMA_TX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + +void DMA_RX_IRQHandler(void) +{ + MXC_DMA_Handler(); } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -101,12 +115,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } - txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; @@ -115,16 +124,14 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); - if (rxnum == I2C_BYTES) { - i2c->inten0 |= MXC_F_I2C_INTFL0_ADDR_MATCH; + i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } break; case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -140,9 +147,10 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -157,6 +165,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -195,7 +204,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -206,25 +215,34 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); + if (error != E_NO_ERROR) { + printf("Failed master\n"); + return error; + } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); if (error != E_NO_ERROR) { - printf("-->Failed master\n"); + printf("Failed DMA master\n"); return error; - } else { - printf("\n-->I2C Master Initialization Complete"); } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); - if (error != E_NO_ERROR) { printf("Failed slave\n"); return error; - } else { - printf("\n-->I2C Slave Initialization Complete"); } + printf("\n-->I2C Slave Initialization Complete"); + + MXC_NVIC_SetVector(I2C0_IRQn, I2C0_IRQHandler); NVIC_EnableIRQ(I2C0_IRQn); + __enable_irq(); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); @@ -258,23 +276,42 @@ int main() return error; } +#ifdef MASTERDMA + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); + + if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { + printf("Error writing: %d\n", error); + return error; + } +#else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); + LED_On(LED_GREEN); } else { printf("\n-->I2C Transaction Failed\n"); + LED_On(LED_RED); return E_FAIL; } diff --git a/Examples/MAX32672/I2C/README.md b/Examples/MAX32672/I2C/README.md index ea76e3132a..4b64dd17ea 100644 --- a/Examples/MAX32672/I2C/README.md +++ b/Examples/MAX32672/I2C/README.md @@ -22,7 +22,7 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -40,9 +40,9 @@ at JP4 and JP5. -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32672/I2C/main.c b/Examples/MAX32672/I2C/main.c index 3ef22155dc..bd75630995 100644 --- a/Examples/MAX32672/I2C/main.c +++ b/Examples/MAX32672/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,6 +45,7 @@ */ /***** Includes *****/ + #include #include #include @@ -55,24 +56,29 @@ #include "dma.h" /***** Definitions *****/ + +#define MASTERDMA //Comment this line out if standard I2C transaction is required + #define I2C_MASTER MXC_I2C0 #define I2C_SLAVE MXC_I2C2 #define I2C_FREQ 100000 #define I2C_SLAVE_ADDR (0x51) -#define I2C_BYTES 100 +#define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; volatile int rxnum = 0; -volatile int num; + /***** Functions *****/ //Slave interrupt handler @@ -81,6 +87,16 @@ void I2C2_IRQHandler(void) MXC_I2C_AsyncHandler(I2C_SLAVE); } +void DMA_TX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + +void DMA_RX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { @@ -97,12 +113,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } - txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; @@ -111,16 +122,14 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); - if (rxnum == I2C_BYTES) { - i2c->inten0 |= MXC_F_I2C_INTFL0_ADDR_MATCH; + i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } break; case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -136,9 +145,10 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -153,6 +163,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -191,7 +202,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -203,25 +214,36 @@ int main() int error, i = 0; - //Set up the I2C Master + //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { - printf("-->Failed master\n"); + printf("Failed master\n"); + return error; + } + +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); return error; - } else { - printf("\n-->I2C Master Initialization Complete"); } +#endif - //Set up the I2C Slave + printf("\n-->I2C Master Initialization Complete"); + + //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); if (error != E_NO_ERROR) { printf("Failed slave\n"); return error; - } else { - printf("\n-->I2C Slave Initialization Complete"); } + printf("\n-->I2C Slave Initialization Complete"); + + MXC_NVIC_SetVector(I2C2_IRQn, I2C2_IRQHandler); NVIC_EnableIRQ(I2C2_IRQn); + __enable_irq(); // Set I2C frequency MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); @@ -256,20 +278,36 @@ int main() return error; } - // Run I2C transaction with I2C0 +#ifdef MASTERDMA + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); + + if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { + printf("Error writing: %d\n", error); + return error; + } +#else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32675/I2C/README.md b/Examples/MAX32675/I2C/README.md index aa308f3085..51e19eed72 100644 --- a/Examples/MAX32675/I2C/README.md +++ b/Examples/MAX32675/I2C/README.md @@ -36,9 +36,9 @@ P0.19 to P0.7 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32675/I2C/main.c b/Examples/MAX32675/I2C/main.c index 4c0415d289..0d84ece7ec 100644 --- a/Examples/MAX32675/I2C/main.c +++ b/Examples/MAX32675/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,50 +45,64 @@ */ /***** Includes *****/ + #include #include #include #include "mxc_device.h" #include "mxc_delay.h" +#include "mxc_errors.h" #include "nvic_table.h" #include "i2c.h" #include "dma.h" +#include "led.h" /***** Definitions *****/ -// #define MASTERDMA -#define I2C_MASTER MXC_I2C2 -#define I2C_SLAVE MXC_I2C0 +#define MASTERDMA //Comment this line out if standard I2C transaction is required + +#define I2C_MASTER MXC_I2C0 +#define I2C_SLAVE MXC_I2C2 #define I2C_FREQ 100000 #define I2C_SLAVE_ADDR (0x51) -#define I2C_BYTES 100 +#define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; volatile int rxnum = 0; -volatile int num; + /***** Functions *****/ //Slave interrupt handler -void I2C0_IRQHandler(void) +void I2C2_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; +} + +void DMA_TX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + +void DMA_RX_IRQHandler(void) +{ + MXC_DMA_Handler(); } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -101,12 +115,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } - txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; @@ -115,16 +124,14 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); - if (rxnum == I2C_BYTES) { - i2c->inten0 |= MXC_F_I2C_INTFL0_ADDR_MATCH; + i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } break; case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -140,9 +147,10 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -157,6 +165,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -195,7 +204,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -206,25 +215,34 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); + if (error != E_NO_ERROR) { + printf("Failed master\n"); + return error; + } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); if (error != E_NO_ERROR) { - printf("-->Failed master\n"); + printf("Failed DMA master\n"); return error; - } else { - printf("\n-->I2C Master Initialization Complete"); } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); - if (error != E_NO_ERROR) { printf("Failed slave\n"); return error; - } else { - printf("\n-->I2C Slave Initialization Complete"); } - NVIC_EnableIRQ(I2C0_IRQn); + printf("\n-->I2C Slave Initialization Complete"); + + MXC_NVIC_SetVector(I2C2_IRQn, I2C2_IRQHandler); + NVIC_EnableIRQ(I2C2_IRQn); + __enable_irq(); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); @@ -258,19 +276,36 @@ int main() return error; } +#ifdef MASTERDMA + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); + + if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { + printf("Error writing: %d\n", error); + return error; + } +#else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32680/I2C/README.md b/Examples/MAX32680/I2C/README.md index 4456d5bc3f..4f6bea53b5 100644 --- a/Examples/MAX32680/I2C/README.md +++ b/Examples/MAX32680/I2C/README.md @@ -27,7 +27,7 @@ Universal instructions on building, flashing, and debugging this project can be The Console UART of the device will output these messages: ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -42,9 +42,9 @@ P0.11 to P0.17 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32680/I2C/main.c b/Examples/MAX32680/I2C/main.c index abb37c79ba..a442856629 100644 --- a/Examples/MAX32680/I2C/main.c +++ b/Examples/MAX32680/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. For * this example you must connect P0.10 to P0.16 (SCL) and P0.11 to P0.17 (SCL). The Master * will use P0.10 and P0.11. The Slave will use P0.16 and P0.17. You must also @@ -51,40 +51,51 @@ #include "dma.h" /***** Definitions *****/ -// #define MASTERDMA + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C1 #define I2C_SLAVE MXC_I2C0 #define I2C_FREQ 100000 #define I2C_SLAVE_ADDR (0x51) -#define I2C_BYTES 100 +#define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; volatile int rxnum = 0; -volatile int num; + /***** Functions *****/ //Slave interrupt handler void I2C0_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; +} + +void DMA_TX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + +void DMA_RX_IRQHandler(void) +{ + MXC_DMA_Handler(); } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -97,12 +108,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } - txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; @@ -111,7 +117,6 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); - if (rxnum == I2C_BYTES) { i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } @@ -120,7 +125,6 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -135,10 +139,11 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); - printf("i2c->int_fl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -153,6 +158,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -191,7 +197,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -202,26 +208,34 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); + if (error != E_NO_ERROR) { + printf("Failed master\n"); + return error; + } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); if (error != E_NO_ERROR) { - printf("-->Failed master\n"); + printf("Failed DMA master\n"); return error; - } else { - printf("\n-->I2C Master Initialization Complete"); } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); - if (error != E_NO_ERROR) { printf("Failed slave\n"); return error; - } else { - printf("\n-->I2C Slave Initialization Complete"); } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C0_IRQn, I2C0_IRQHandler); NVIC_EnableIRQ(I2C0_IRQn); + __enable_irq(); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); @@ -255,19 +269,36 @@ int main() return error; } +#ifdef MASTERDMA + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); + + if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { + printf("Error writing: %d\n", error); + return error; + } +#else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Examples/MAX32690/I2C/README.md b/Examples/MAX32690/I2C/README.md index bb01a39bc1..636a722086 100644 --- a/Examples/MAX32690/I2C/README.md +++ b/Examples/MAX32690/I2C/README.md @@ -31,7 +31,7 @@ If using the MAX32690FTHR: The Console UART of the device will output these messages: ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -46,9 +46,9 @@ P1.7->P2.7 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX32690/I2C/main.c b/Examples/MAX32690/I2C/main.c index fd02f339a9..f2db68c943 100644 --- a/Examples/MAX32690/I2C/main.c +++ b/Examples/MAX32690/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,6 +45,7 @@ */ /***** Includes *****/ + #include #include #include @@ -57,6 +58,7 @@ #include "led.h" /***** Definitions *****/ + #define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C0 @@ -67,11 +69,13 @@ #define I2C_BYTES 255 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; @@ -83,28 +87,22 @@ volatile int rxnum = 0; void I2C2_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; } -void DMA0_IRQHandler(void) +void DMA_TX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(0); - DMA_FLAG = 1; } -void DMA1_IRQHandler(void) +void DMA_RX_IRQHandler(void) { MXC_DMA_Handler(); - MXC_DMA_ReleaseChannel(1); - DMA_FLAG = 1; } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -115,22 +113,23 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) // Clear bytes written rxnum = 0; break; + case MXC_I2C_EVT_MASTER_RD: // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; break; + case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); if (rxnum == I2C_BYTES) { i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } + break; + case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: // Write as much data as possible into TX FIFO @@ -138,23 +137,27 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) if (txcnt >= txnum) { break; } + int num = MXC_I2C_GetTXFIFOAvailable(i2c); num = (num > (txnum - txcnt)) ? (txnum - txcnt) : num; txcnt += MXC_I2C_WriteTXFIFO(i2c, &Stxdata[txcnt], num); break; + default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); return 1; } } + return 0; } @@ -162,12 +165,15 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); + for (i = 0; i < sizeof(txdata); ++i) { printf("%02x ", txdata[i]); } printf("\n\n-->RxData: "); + for (i = 0; i < sizeof(rxdata); ++i) { printf("%02x ", rxdata[i]); } @@ -181,11 +187,13 @@ void printData(void) int verifyData(void) { int i, fails = 0; + for (i = 0; i < I2C_BYTES; ++i) { if (txdata[i] != rxdata[i]) { ++fails; } } + if (fails > 0) { return E_FAIL; } @@ -196,7 +204,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -208,9 +216,20 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); if (error != E_NO_ERROR) { - printf("Failed master\n"); + printf("Failed master.\n"); + return error; + } + +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); + if (error != E_NO_ERROR) { + printf("Failed DMA master\n"); return error; } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); @@ -219,6 +238,8 @@ int main() return error; } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C2_IRQn, I2C2_IRQHandler); NVIC_EnableIRQ(I2C2_IRQn); __enable_irq(); @@ -231,6 +252,8 @@ int main() for (i = 0; i < I2C_BYTES; i++) { txdata[i] = i; rxdata[i] = 0; + Stxdata[i] = i; + Srxdata[i] = 0; } // This will write data to slave @@ -254,37 +277,39 @@ int main() } #ifdef MASTERDMA - MXC_DMA_ReleaseChannel(0); - MXC_DMA_ReleaseChannel(1); + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); - NVIC_EnableIRQ(DMA0_IRQn); - NVIC_EnableIRQ(DMA1_IRQn); - __enable_irq(); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } - while (DMA_FLAG == 0) {} #else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} -#endif printf("\n-->Result: \n"); printData(); printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); - LED_On(LED_GREEN); } else { printf("\n-->I2C Transaction Failed\n"); - LED_On(LED_RED); return E_FAIL; } diff --git a/Examples/MAX78002/I2C/README.md b/Examples/MAX78002/I2C/README.md index 688f259868..9e4feaab84 100644 --- a/Examples/MAX78002/I2C/README.md +++ b/Examples/MAX78002/I2C/README.md @@ -22,7 +22,7 @@ Universal instructions on building, flashing, and debugging this project can be ## Expected Output ``` -******** I2C SLAVE ASYNC TRANSACTION TEST ********* +******** I2C Master-Slave Transaction Demo ********* This example uses one I2C peripheral as a master to read and write to another I2C which acts as a slave. @@ -37,9 +37,9 @@ P0.11 to P0.17 (SDA). -->Result: --->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->TxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe --->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 +-->RxData: 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe -->I2C Transaction Successful diff --git a/Examples/MAX78002/I2C/main.c b/Examples/MAX78002/I2C/main.c index 28a2595279..89119c4cf3 100644 --- a/Examples/MAX78002/I2C/main.c +++ b/Examples/MAX78002/I2C/main.c @@ -33,7 +33,7 @@ /** * @file main.c - * @brief I2C Loopback Example + * @brief I2C Master-Slave Transaction Demo * @details This example uses the I2C Master to read/write from/to the I2C Slave. * For this example, user must connect I2C Master SCL pin to I2C Slave SCL * pin and I2C Master SDA pin to I2C Slave SDA pin. User must also connect @@ -45,6 +45,7 @@ */ /***** Includes *****/ + #include #include #include @@ -55,7 +56,8 @@ #include "dma.h" /***** Definitions *****/ -// #define MASTERDMA + +#define MASTERDMA //Comment this line out if standard I2C transaction is required #define I2C_MASTER MXC_I2C1 #define I2C_SLAVE MXC_I2C0 @@ -65,30 +67,40 @@ #define I2C_BYTES 100 /***** Globals *****/ + static uint8_t Stxdata[I2C_BYTES]; static uint8_t Srxdata[I2C_BYTES]; static uint8_t txdata[I2C_BYTES]; static uint8_t rxdata[I2C_BYTES]; -volatile uint8_t DMA_FLAG = 0; +int8_t DMA_TX_CH; +int8_t DMA_RX_CH; volatile int I2C_FLAG; volatile int txnum = 0; volatile int txcnt = 0; volatile int rxnum = 0; -volatile int num; + /***** Functions *****/ //Slave interrupt handler void I2C0_IRQHandler(void) { MXC_I2C_AsyncHandler(I2C_SLAVE); - return; +} + +void DMA_TX_IRQHandler(void) +{ + MXC_DMA_Handler(); +} + +void DMA_RX_IRQHandler(void) +{ + MXC_DMA_Handler(); } //I2C callback function void I2C_Callback(mxc_i2c_req_t *req, int error) { I2C_FLAG = error; - return; } int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) @@ -101,12 +113,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) break; case MXC_I2C_EVT_MASTER_RD: - // Serve as a 16 byte loopback, returning data*2 - for (int i = 0; i < I2C_BYTES; i++) { - Stxdata[i] = Srxdata[i]; - } - txnum = I2C_BYTES; txcnt = 0; i2c->intfl0 = MXC_F_I2C_INTFL0_TX_LOCKOUT | MXC_F_I2C_INTFL0_ADDR_MATCH; @@ -115,7 +122,6 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_RX_THRESH: case MXC_I2C_EVT_OVERFLOW: rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); - if (rxnum == I2C_BYTES) { i2c->inten0 |= MXC_F_I2C_INTEN0_ADDR_MATCH; } @@ -124,7 +130,6 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) case MXC_I2C_EVT_TX_THRESH: case MXC_I2C_EVT_UNDERFLOW: - // Write as much data as possible into TX FIFO // Unless we're at the end of the transaction (only write what's needed) if (txcnt >= txnum) { @@ -139,10 +144,11 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) default: if (*((int *)data) == E_COMM_ERR) { printf("I2C Slave Error!\n"); - printf("i2c->int_fl0 = 0x%08x\n", i2c->intfl0); - printf("i2c->status = 0x%08x\n", i2c->status); + printf("i2c->intfl0 = 0x%08x\n", i2c->intfl0); + printf("i2c->status = 0x%08x\n", i2c->status); I2C_Callback(NULL, E_COMM_ERR); return 1; + } else if (*((int *)data) == E_NO_ERROR) { rxnum += MXC_I2C_ReadRXFIFO(i2c, &Srxdata[rxnum], MXC_I2C_GetRXFIFOAvailable(i2c)); I2C_Callback(NULL, E_NO_ERROR); @@ -157,6 +163,7 @@ int slaveHandler(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_t event, void *data) void printData(void) { int i; + printf("\n-->TxData: "); for (i = 0; i < sizeof(txdata); ++i) { @@ -195,7 +202,7 @@ int verifyData(void) // ***************************************************************************** int main() { - printf("\n******** I2C SLAVE ASYNC TRANSACTION TEST *********\n"); + printf("\n******** I2C Master-Slave Transaction Demo *********\n"); printf("\nThis example uses one I2C peripheral as a master to\n"); printf("read and write to another I2C which acts as a slave.\n"); @@ -206,26 +213,34 @@ int main() //Setup the I2CM error = MXC_I2C_Init(I2C_MASTER, 1, 0); + if (error != E_NO_ERROR) { + printf("Failed master.\n"); + return error; + } +#ifdef MASTERDMA + //Setup the I2CM DMA + error = MXC_I2C_DMA_Init(I2C_MASTER, MXC_DMA, true, true); if (error != E_NO_ERROR) { - printf("-->Failed master\n"); + printf("Failed DMA master\n"); return error; - } else { - printf("\n-->I2C Master Initialization Complete"); } +#endif + + printf("\n-->I2C Master Initialization Complete"); //Setup the I2CS error = MXC_I2C_Init(I2C_SLAVE, 0, I2C_SLAVE_ADDR); - if (error != E_NO_ERROR) { printf("Failed slave\n"); return error; - } else { - printf("\n-->I2C Slave Initialization Complete"); } + printf("\n-->I2C Slave Initialization Complete"); + MXC_NVIC_SetVector(I2C0_IRQn, I2C0_IRQHandler); NVIC_EnableIRQ(I2C0_IRQn); + __enable_irq(); MXC_I2C_SetFrequency(I2C_MASTER, I2C_FREQ); @@ -259,19 +274,36 @@ int main() return error; } +#ifdef MASTERDMA + DMA_TX_CH = MXC_I2C_DMA_GetTXChannel(I2C_MASTER); + DMA_RX_CH = MXC_I2C_DMA_GetRXChannel(I2C_MASTER); + + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_TX_CH)); + NVIC_EnableIRQ(MXC_DMA_CH_GET_IRQ(DMA_RX_CH)); + + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_TX_CH), DMA_TX_IRQHandler); + MXC_NVIC_SetVector(MXC_DMA_CH_GET_IRQ(DMA_RX_CH), DMA_RX_IRQHandler); + + if ((error = MXC_I2C_MasterTransactionDMA(&reqMaster)) != 0) { + printf("Error writing: %d\n", error); + return error; + } +#else if ((error = MXC_I2C_MasterTransaction(&reqMaster)) != 0) { printf("Error writing: %d\n", error); return error; } +#endif while (I2C_FLAG == 1) {} printf("\n-->Result: \n"); - printData(); - printf("\n"); + MXC_I2C_Shutdown(I2C_MASTER); + MXC_I2C_Shutdown(I2C_SLAVE); + if (verifyData() == E_NO_ERROR) { printf("\n-->I2C Transaction Successful\n"); } else { diff --git a/Libraries/PeriphDrivers/Include/MAX32520/i2c.h b/Libraries/PeriphDrivers/Include/MAX32520/i2c.h index 08e9d8c39f..ce290f72c1 100644 --- a/Libraries/PeriphDrivers/Include/MAX32520/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32520/i2c.h @@ -1,5 +1,5 @@ /** -* @file i2c.h +* @file i2c.h * @brief Inter-integrated circuit (I2C) communications interface driver. */ @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32520_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -54,6 +56,8 @@ extern "C" { * @{ */ +/***** Definitions *****/ + typedef struct _i2c_req_t mxc_i2c_req_t; /** @@ -191,14 +195,14 @@ typedef int (*mxc_i2c_slave_handler_t)(mxc_i2c_regs_t *i2c, mxc_i2c_slave_event_ int MXC_I2C_Init(mxc_i2c_regs_t *i2c, int masterMode, unsigned int slaveAddr); /** - * @brief Set slave address for I2C instances acting as slaves on the bus. - * @note Set idx to zero, multiple I2C instances acting as slaves on the - * bus is not yet supported. + * @brief Initialize and enable I2C peripheral. + * @note Set idx to 0, multiple I2C instances acting as slaves is not yet + * supported. * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param slaveAddr 7-bit or 10-bit address to use when in slave mode. * This parameter is ignored when masterMode is non-zero. - * @param idx Index of the I2C slave. + * @param idx Index of the I2C slave instance. * * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ @@ -279,6 +283,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -413,13 +465,13 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig /** * @brief Unloads bytes from the receive FIFO using DMA for longer reads. - * - * @note The operation is not complete until the callback has been called + * This function does not initialize the DMA or acquire any DMA channels. * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param bytes The buffer to read the data into. * @param len The number of bytes to read. - * @param callback The function to call when the read is complete + * @param callback The function to call when the read is complete. This parameter + * was never used but it's left in to preserve project builds. * * @return See \ref MXC_Error_Codes for a list of return values. */ @@ -448,12 +500,14 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi /** * @brief Loads bytes into the transmit FIFO using DMA for longer writes. + * This function does not initialize the DMA or acquire any DMA channels. * * @note The operation is not complete until the callback has been called * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param bytes The buffer containing the bytes to write * @param len The number of bytes to write. - * @param callback The function to call when the read is complete + * @param callback The function to call when the read is complete. This parameter + * was never used but it's left in to preserve project builds. * * @return See \ref MXC_Error_Codes for a list of return values */ @@ -487,8 +541,8 @@ void MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t *i2c); * @brief Get the presently set interrupt flags. * * @param i2c Pointer to I2C registers (selects the I2C block used.) - * @param flags0 Pointer to variable to store flags currently set in intfl0 - * @param flags1 Pointer to variable to store flags currently set in intfl1 + * @param flags0 Pointer to store flags currently set in interrupt register intfl0. + * @param flags1 Pointer to store flags currently set in interrupt register intfl1. * * @return See \ref MXC_Error_Codes for a list of return values */ @@ -498,8 +552,8 @@ int MXC_I2C_GetFlags(mxc_i2c_regs_t *i2c, unsigned int *flags0, unsigned int *fl * @brief Clears the Interrupt Flags. * * @param i2c Pointer to I2C registers (selects the I2C block used.) - * @param flags0 Interrupts to be cleared in intfl0 - * @param flags1 Interrupts to be enabled in intfl1 + * @param flags0 Flags to be cleared in interrupt register intfl0. + * @param flags1 Flags to be cleared in interrupt register intfl1. */ void MXC_I2C_ClearFlags(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1); @@ -604,7 +658,7 @@ int MXC_I2C_Recover(mxc_i2c_regs_t *i2c, unsigned int retries); /* ************************************************************************* */ /** - * @brief Performs a blocking I2C master transaction. + * @brief Performs a blocking I2C Master transaction. * * Performs a blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. @@ -655,7 +709,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32570/i2c.h b/Libraries/PeriphDrivers/Include/MAX32570/i2c.h index 07afb3bf85..949dc5cbd8 100644 --- a/Libraries/PeriphDrivers/Include/MAX32570/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32570/i2c.h @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32570_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -278,6 +280,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -563,8 +613,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -659,7 +707,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32572/i2c.h b/Libraries/PeriphDrivers/Include/MAX32572/i2c.h index 616e1a81b8..9fa7676de7 100644 --- a/Libraries/PeriphDrivers/Include/MAX32572/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32572/i2c.h @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32572_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -284,6 +286,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -569,8 +619,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -665,7 +713,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32650/i2c.h b/Libraries/PeriphDrivers/Include/MAX32650/i2c.h index b932ced85d..b4d6a57fd3 100644 --- a/Libraries/PeriphDrivers/Include/MAX32650/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32650/i2c.h @@ -40,8 +40,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32650_I2C_H_ #include +#include #include "i2c_regs.h" #include "mxc_sys.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -271,6 +273,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -647,7 +697,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32655/i2c.h b/Libraries/PeriphDrivers/Include/MAX32655/i2c.h index 11df9554b4..83c3b6e814 100644 --- a/Libraries/PeriphDrivers/Include/MAX32655/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32655/i2c.h @@ -1,6 +1,6 @@ /** -* @file -* @brief Inter-integrated circuit (I2C) communications interface driver. +* @file i2c.h +* @brief Inter-integrated circuit (I2C) communications interface driver. */ /****************************************************************************** @@ -41,9 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32655_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" -/***** Definitions *****/ +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -285,6 +286,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -565,8 +614,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -660,8 +707,14 @@ int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req); int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** - * @brief Performs a non-blocking I2C transaction using DMA for reduced time - * in the ISR. + * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32660/i2c.h b/Libraries/PeriphDrivers/Include/MAX32660/i2c.h index 2cfb1f156f..5011e51e2e 100644 --- a/Libraries/PeriphDrivers/Include/MAX32660/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32660/i2c.h @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32660_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -275,6 +277,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -557,8 +607,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -653,7 +701,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32662/i2c.h b/Libraries/PeriphDrivers/Include/MAX32662/i2c.h index 62339ede1e..7ce46b8d43 100644 --- a/Libraries/PeriphDrivers/Include/MAX32662/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32662/i2c.h @@ -1,6 +1,6 @@ /** -* @file -* @brief Inter-integrated circuit (I2C) communications interface driver. +* @file i2c.h +* @brief Inter-integrated circuit (I2C) communications interface driver. */ /****************************************************************************** @@ -41,9 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32662_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" -/***** Definitions *****/ +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -279,6 +280,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -559,8 +608,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -654,8 +701,14 @@ int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req); int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** - * @brief Performs a non-blocking I2C transaction using DMA for reduced time - * in the ISR. + * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32665/dma.h b/Libraries/PeriphDrivers/Include/MAX32665/dma.h index 4ee96f424b..82e39f5875 100644 --- a/Libraries/PeriphDrivers/Include/MAX32665/dma.h +++ b/Libraries/PeriphDrivers/Include/MAX32665/dma.h @@ -122,6 +122,8 @@ typedef enum { MXC_S_DMA_CFG_REQSEL_I2C0TX, /**< I2C0 Transmit DMA Request Selection */ MXC_DMA_REQUEST_I2C1TX = MXC_S_DMA_CFG_REQSEL_I2C1TX, /**< I2C1 Transmit DMA Request Selection */ + MXC_DMA_REQUEST_I2C2TX = + MXC_S_DMA_CFG_REQSEL_I2C2TX, /**< I2C2 Transmit DMA Request Selection */ MXC_DMA_REQUEST_UART2TX = MXC_S_DMA_CFG_REQSEL_UART2TX, /**< UART 2 Transmit DMA Request Selection */ //MXC_DMA_REQUEST_SPI3TX = MXC_S_DMA_CFG_REQSEL_SPI3TX, /**< SPI3 Transmit DMA Request Selection */ diff --git a/Libraries/PeriphDrivers/Include/MAX32665/i2c.h b/Libraries/PeriphDrivers/Include/MAX32665/i2c.h index 9b0f6b6348..137efd7b82 100644 --- a/Libraries/PeriphDrivers/Include/MAX32665/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32665/i2c.h @@ -41,9 +41,11 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32665_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" #include "dma.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -276,6 +278,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ diff --git a/Libraries/PeriphDrivers/Include/MAX32670/i2c.h b/Libraries/PeriphDrivers/Include/MAX32670/i2c.h index 9f03fb3609..fd0bfa32f0 100644 --- a/Libraries/PeriphDrivers/Include/MAX32670/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32670/i2c.h @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32670_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -285,6 +287,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -419,13 +469,13 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig /** * @brief Unloads bytes from the receive FIFO using DMA for longer reads. - * - * @note The operation is not complete until the callback has been called + * This function does not initialize the DMA or acquire any DMA channels. * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param bytes The buffer to read the data into. * @param len The number of bytes to read. - * @param callback The function to call when the read is complete + * @param callback The function to call when the read is complete. This parameter + * was never used but it's left in to preserve project builds. * * @return See \ref MXC_Error_Codes for a list of return values. */ @@ -454,12 +504,14 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi /** * @brief Loads bytes into the transmit FIFO using DMA for longer writes. + * This function does not initialize the DMA or acquire any DMA channels. * * @note The operation is not complete until the callback has been called * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param bytes The buffer containing the bytes to write * @param len The number of bytes to write. - * @param callback The function to call when the read is complete + * @param callback The function to call when the read is complete. This parameter + * was never used but it's left in to preserve project builds. * * @return See \ref MXC_Error_Codes for a list of return values */ @@ -567,8 +619,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -663,7 +713,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32672/i2c.h b/Libraries/PeriphDrivers/Include/MAX32672/i2c.h index 2b98ce936f..b2b54e6c4c 100644 --- a/Libraries/PeriphDrivers/Include/MAX32672/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32672/i2c.h @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32672_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -286,6 +288,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -571,8 +621,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -667,7 +715,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32675/i2c.h b/Libraries/PeriphDrivers/Include/MAX32675/i2c.h index be6115996a..183c886d6a 100644 --- a/Libraries/PeriphDrivers/Include/MAX32675/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32675/i2c.h @@ -41,8 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32675_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -285,6 +287,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -567,8 +617,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -663,7 +711,13 @@ int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time - * in the ISR. + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32680/i2c.h b/Libraries/PeriphDrivers/Include/MAX32680/i2c.h index 7b05305870..7e308ce204 100644 --- a/Libraries/PeriphDrivers/Include/MAX32680/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32680/i2c.h @@ -1,6 +1,6 @@ /** -* @file -* @brief Inter-integrated circuit (I2C) communications interface driver. +* @file i2c.h +* @brief Inter-integrated circuit (I2C) communications interface driver. */ /****************************************************************************** @@ -41,9 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32680_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" -/***** Definitions *****/ +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -285,6 +286,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -565,8 +614,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -660,8 +707,14 @@ int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req); int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** - * @brief Performs a non-blocking I2C transaction using DMA for reduced time - * in the ISR. + * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX32690/i2c.h b/Libraries/PeriphDrivers/Include/MAX32690/i2c.h index dec0f795f7..a20fc8f2b8 100644 --- a/Libraries/PeriphDrivers/Include/MAX32690/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX32690/i2c.h @@ -1,6 +1,6 @@ /** -* @file -* @brief Inter-integrated circuit (I2C) communications interface driver. +* @file i2c.h +* @brief Inter-integrated circuit (I2C) communications interface driver. */ /****************************************************************************** @@ -41,9 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX32690_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" -/***** Definitions *****/ +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -285,6 +286,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -565,8 +614,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -660,8 +707,14 @@ int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req); int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** - * @brief Performs a non-blocking I2C transaction using DMA for reduced time - * in the ISR. + * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX78000/i2c.h b/Libraries/PeriphDrivers/Include/MAX78000/i2c.h index ef7ce11145..fa82226050 100644 --- a/Libraries/PeriphDrivers/Include/MAX78000/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX78000/i2c.h @@ -41,9 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX78000_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" -/***** Definitions *****/ +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -279,6 +280,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -652,8 +701,14 @@ int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req); int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** - * @brief Performs a non-blocking I2C transaction using DMA for reduced time - * in the ISR. + * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Include/MAX78002/i2c.h b/Libraries/PeriphDrivers/Include/MAX78002/i2c.h index aacae5002f..360eafa608 100644 --- a/Libraries/PeriphDrivers/Include/MAX78002/i2c.h +++ b/Libraries/PeriphDrivers/Include/MAX78002/i2c.h @@ -41,9 +41,10 @@ #define LIBRARIES_PERIPHDRIVERS_INCLUDE_MAX78002_I2C_H_ #include +#include #include "mxc_sys.h" #include "i2c_regs.h" -/***** Definitions *****/ +#include "dma_regs.h" #ifdef __cplusplus extern "C" { @@ -285,6 +286,54 @@ int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable); */ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c); +/** + * @brief Initializes the DMA for I2C DMA transactions. + * + * This function will release any acquired DMA channels before reacquiring and + * reconfiguring selected I2C DMA TX or RX channels. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param dma Pointer to DMA registers (selects the DMA block used). + * @param use_dma_tx If true, acquire and configure DMA TX channel, else release any + * acquired DMA TX channel. + * @param use_dma_rx If true, acquire and configure DMA RX channel, else release any + * acquired DMA RX channel. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx); + +/** + * @brief Retreive the DMA TX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA TX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Retreive the DMA RX Channel associated with I2C instance. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * + * @return If successful, the DMA RX Channel number is returned. Otherwise, see + * \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c); + +/** + * @brief Sets the I2C instance's DMA TX/RX request select. + * + * @param i2c Pointer to I2C registers (selects the I2C block used). + * @param txData Pointer to transmit buffer. + * @param rxData Pointer to receive buffer. + * + * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. + */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData); + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -569,8 +618,6 @@ void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c); * * @param i2c Pointer to I2C registers (selects the I2C block used.) * @param timeout Timeout in uS - * - * @return Success/Fail, see \ref MXC_Error_Codes for a list of return codes. */ void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout); @@ -664,8 +711,14 @@ int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req); int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req); /** - * @brief Performs a non-blocking I2C transaction using DMA for reduced time - * in the ISR. + * @brief Performs a non-blocking I2C Master transaction using DMA for reduced time + * in the ISR. This function initializes the DMA and acquires DMA channels + * if MXC_I2C_DMA_Init(...) was not called earlier. + * + * It is recommended to initialize the DMA by calling MXC_I2C_DMA_Init(...) function + * before calling MXC_I2C_MasterTransactionDMA(...). This provides flexibility in + * setting up generic DMA channel vectors during run-time without knowing what DMA + * channels will be acquired beforehand. * * Performs a non-blocking I2C transaction. These actions will be performed: * 1. If necessary, generate a start condition on the bus. diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_ai87.c b/Libraries/PeriphDrivers/Source/I2C/i2c_ai87.c index 50f309e612..2caa81e868 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_ai87.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_ai87.c @@ -102,7 +102,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -146,6 +146,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -193,23 +263,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -225,23 +280,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_es17.c b/Libraries/PeriphDrivers/Source/I2C/i2c_es17.c index 4798bc4f39..d9ac5fdcfe 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_es17.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_es17.c @@ -112,7 +112,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -157,6 +157,60 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -204,18 +258,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - } - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -231,18 +275,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - } - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me10.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me10.c index dc8e277a1e..7998542f29 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me10.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me10.c @@ -120,7 +120,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_BAD_PARAM; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } /* ************************************************************************** */ @@ -160,6 +160,72 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +/* ************************************************************************* */ +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +/* ************************************************************************* */ +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +/* ************************************************************************* */ +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +/* ************************************************************************* */ +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************** */ int MXC_I2C_Start(mxc_i2c_regs_t *i2c) { @@ -213,21 +279,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - mxc_dma_config_t config; - - switch (MXC_I2C_GET_IDX(i2c)) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - default: - return E_BAD_PARAM; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } /* ************************************************************************** */ @@ -246,21 +299,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - mxc_dma_config_t config; - - switch (MXC_I2C_GET_IDX(i2c)) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - default: - return E_BAD_PARAM; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } /* ************************************************************************** */ diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me11.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me11.c index 33c5fd2aac..b882e03e8b 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me11.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me11.c @@ -139,7 +139,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_BAD_PARAM; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_SetFrequency(mxc_i2c_regs_t *i2c, unsigned int hz) @@ -167,6 +167,68 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -214,22 +276,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -245,22 +293,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me12.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me12.c index e189c332da..10c96e961e 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me12.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me12.c @@ -98,7 +98,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -140,6 +140,68 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -187,23 +249,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -219,23 +266,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me13.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me13.c index 7a8c8b6d4d..42337d941e 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me13.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me13.c @@ -103,7 +103,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -152,6 +152,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -199,22 +269,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -230,21 +286,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me14.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me14.c index 740aa3f16e..3b47c6311d 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me14.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me14.c @@ -121,7 +121,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_BAD_PARAM; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_SetFrequency(mxc_i2c_regs_t *i2c, unsigned int hz) @@ -149,6 +149,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -196,29 +266,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback, mxc_dma_regs_t *dma) { - uint8_t i2cNum; - mxc_dma_config_t config; - - if (MXC_DMA_GET_IDX(dma) == -1) { - return E_BAD_PARAM; - } - - i2cNum = MXC_I2C_GET_IDX(i2c); - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - - case 2: - config.reqsel = MXC_DMA_REQUEST_I2C2RX; - break; - } - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, dma); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, dma); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -234,25 +283,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback, mxc_dma_regs_t *dma) { - uint8_t i2cNum; - mxc_dma_config_t config; - - if (MXC_DMA_GET_IDX(dma) == -1) { - return E_BAD_PARAM; - } - - i2cNum = MXC_I2C_GET_IDX(i2c); - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, dma); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, dma); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me15.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me15.c index 681c4a26a9..85f9df5107 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me15.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me15.c @@ -44,6 +44,9 @@ #include "dma_regs.h" #include "i2c.h" #include "i2c_reva.h" +#include "dma.h" +#include "dma_reva.h" +#include "dma_reva_regs.h" /* **** Definitions **** */ #define MXC_I2C_MAX_ADDR_WIDTH 0x7F @@ -133,7 +136,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -177,6 +180,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -199,8 +272,6 @@ int MXC_I2C_ReadByte(mxc_i2c_regs_t *i2c, unsigned char *byte, int ack) { return MXC_I2C_RevA_ReadByte((mxc_i2c_reva_regs_t *)i2c, byte, ack); } -// return MXC_I2C_RevA_ReadByteInteractive ((mxc_i2c_reva_regs_t*) i2c, byte, (mxc_i2c_reva_getAck_t) getAck); -// } int MXC_I2C_Write(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len) { @@ -220,26 +291,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - - default: - return E_BAD_PARAM; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -255,26 +308,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - - default: - return E_BAD_PARAM; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me16.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me16.c deleted file mode 100644 index 99f4ad51ed..0000000000 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me16.c +++ /dev/null @@ -1,406 +0,0 @@ -/****************************************************************************** - * Copyright (C) 2023 Maxim Integrated Products, Inc., 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 MAXIM INTEGRATED 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. - * - * Except as contained in this notice, the name of Maxim Integrated - * Products, Inc. shall not be used except as stated in the Maxim Integrated - * Products, Inc. Branding Policy. - * - * The mere transfer of this software does not imply any licenses - * of trade secrets, proprietary technology, copyrights, patents, - * trademarks, maskwork rights, or any other form of intellectual - * property whatsoever. Maxim Integrated Products, Inc. retains all - * ownership rights. - * - ******************************************************************************/ - -#include -#include -#include -#include "mxc_device.h" -#include "mxc_assert.h" -#include "mxc_lock.h" -#include "mxc_sys.h" -#include "mxc_delay.h" -#include "i2c_regs.h" -#include "dma_regs.h" -#include "i2c.h" -#include "i2c_reva.h" - -/* **** Variable Declaration **** */ -uint32_t interruptCheck = MXC_F_I2C_INTFL0_ADDR_MATCH | MXC_F_I2C_INTFL0_DNR_ERR; - -/* **** Function Prototypes **** */ - -/* ************************************************************************* */ -/* Control/Configuration functions */ -/* ************************************************************************* */ -int MXC_I2C_Init(mxc_i2c_regs_t *i2c, int masterMode, unsigned int slaveAddr) -{ - if (i2c == NULL) { - return E_NULL_PTR; - } - - MXC_I2C_Shutdown(i2c); // Clear everything out - - if (i2c == MXC_I2C0) { - MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C0); - MXC_GPIO_Config(&gpio_cfg_i2c0); - } else if (i2c == MXC_I2C1) { - MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C1); - MXC_GPIO_Config(&gpio_cfg_i2c1); - } else if (i2c == MXC_I2C2) { - MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_I2C2); - MXC_GPIO_Config(&gpio_cfg_i2c2); - } else { - return E_NO_DEVICE; - } - - return MXC_I2C_RevA_Init(i2c, masterMode, slaveAddr); -} - -int MXC_I2C_SetSlaveAddr(mxc_i2c_regs_t *i2c, unsigned int slaveAddr, int idx) -{ - if (i2c == NULL) { - return E_NULL_PTR; - } - - if (idx >= MXC_I2C_NUM_TARGET_ADDR) { - return E_NOT_SUPPORTED; - } - - if (slaveAddr > MXC_F_I2C_SLAVE_ADDR) { - // Only support addresses up to 10 bits - return E_BAD_PARAM; - } - - // Set the slave address to operate on - MXC_SETFIELD(i2c->slave, MXC_F_I2C_SLAVE_IDX, (idx << MXC_F_I2C_SLAVE_IDX_POS)); - - if (slaveAddr > MXC_I2C_MAX_ADDR_WIDTH) { - // Set for 10bit addressing mode - i2c->slave |= MXC_F_I2C_SLAVE_EXT_ADDR_EN; - } else { - // Clear for 7bit addressing mode - i2c->slave &= ~MXC_F_I2C_SLAVE_EXT_ADDR_EN; - } - - // Set the slave address - MXC_SETFIELD(i2c->slave, MXC_F_I2C_SLAVE_ADDR, (slaveAddr << MXC_F_I2C_SLAVE_ADDR_POS)); - - // Enable the slave address - i2c->slave &= ~MXC_F_I2C_SLAVE_DIS; - - return E_NO_ERROR; -} - -int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) -{ - // Configure GPIO for I2C - if (i2c == MXC_I2C0) { - MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C0); - MXC_SYS_Reset_Periph(MXC_SYS_RESET0_I2C0); - } else if (i2c == MXC_I2C1) { - MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C1); - MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C1); - } else if (i2c == MXC_I2C2) { - MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_I2C2); - MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C2); - } else { - return E_NO_DEVICE; - } - - return E_NO_ERROR; -} - -int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) -{ - // Configure GPIO for I2C - if (i2c == MXC_I2C0) { - MXC_SYS_Reset_Periph(MXC_SYS_RESET0_I2C0); - } else if (i2c == MXC_I2C1) { - MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C1); - } else if (i2c == MXC_I2C2) { - MXC_SYS_Reset_Periph(MXC_SYS_RESET1_I2C2); - } else { - return E_NO_DEVICE; - } - - return E_NO_ERROR; -} - -int MXC_I2C_SetFrequency(mxc_i2c_regs_t *i2c, unsigned int hz) -{ - return MXC_I2C_RevA_SetFrequency(i2c, hz); -} - -unsigned int MXC_I2C_GetFrequency(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetFrequency(i2c); -} - -int MXC_I2C_ReadyForSleep(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_ReadyForSleep(i2c); -} - -int MXC_I2C_SetClockStretching(mxc_i2c_regs_t *i2c, int enable) -{ - return MXC_I2C_RevA_SetClockStretching(i2c, enable); -} - -int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetClockStretching(i2c); -} - -/* ************************************************************************* */ -/* Low-level functions */ -/* ************************************************************************* */ -int MXC_I2C_Start(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_Start(i2c); -} - -int MXC_I2C_Stop(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_Stop(i2c); -} - -int MXC_I2C_WriteByte(mxc_i2c_regs_t *i2c, unsigned char byte) -{ - return MXC_I2C_RevA_WriteByte(i2c, byte); -} - -int MXC_I2C_ReadByte(mxc_i2c_regs_t *i2c, unsigned char *byte, int ack) -{ - return MXC_I2C_RevA_ReadByte(i2c, byte, ack); -} - -int MXC_I2C_ReadByteInteractive(mxc_i2c_regs_t *i2c, unsigned char *byte, mxc_i2c_getAck_t getAck) -{ - return MXC_I2C_RevA_ReadByteInteractive(i2c, byte, getAck); -} - -int MXC_I2C_Write(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len) -{ - return MXC_I2C_RevA_Write(i2c, bytes, len); -} - -int MXC_I2C_Read(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack) -{ - return MXC_I2C_RevA_Read(i2c, bytes, len, ack); -} - -int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len) -{ - return MXC_I2C_RevA_ReadRXFIFO(i2c, bytes, len); -} - -int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, - mxc_i2c_dma_complete_cb_t callback) -{ - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA(i2c, bytes, len, callback, config); -} - -int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetRXFIFOAvailable(i2c); -} - -int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsigned int len) -{ - return MXC_I2C_RevA_WriteTXFIFO(i2c, bytes, len); -} - -int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, - mxc_i2c_dma_complete_cb_t callback) -{ - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - - return MXC_I2C_RevA_WriteTXFIFODMA(i2c, bytes, len, callback, config); -} - -int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetTXFIFOAvailable(i2c); -} - -void MXC_I2C_ClearRXFIFO(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_ClearRXFIFO(i2c); -} - -void MXC_I2C_ClearTXFIFO(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_ClearTXFIFO(i2c); -} - -int MXC_I2C_GetFlags(mxc_i2c_regs_t *i2c, unsigned int *flags0, unsigned int *flags1) -{ - return MXC_I2C_RevA_GetFlags(i2c, flags0, flags1); -} - -void MXC_I2C_ClearFlags(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1) -{ - MXC_I2C_RevA_ClearFlags(i2c, flags0, flags1); -} - -void MXC_I2C_EnableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1) -{ - MXC_I2C_EnableInt(i2c, flags0, flags1); -} - -void MXC_I2C_DisableInt(mxc_i2c_regs_t *i2c, unsigned int flags0, unsigned int flags1) -{ - MXC_I2C_DisableInt(i2c, flags0, flags1); -} - -void MXC_I2C_EnablePreload(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_EnablePreload((mxc_i2c_reva_regs_t *)i2c); -} - -void MXC_I2C_DisablePreload(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_DisablePreload((mxc_i2c_reva_regs_t *)i2c); -} - -void MXC_I2C_EnableGeneralCall(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_EnableGeneralCall((mxc_i2c_reva_regs_t *)i2c); -} - -void MXC_I2C_DisableGeneralCall(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_DisableGeneralCall((mxc_i2c_reva_regs_t *)i2c); -} - -void MXC_I2C_SetTimeout(mxc_i2c_regs_t *i2c, unsigned int timeout) -{ - MXC_I2C_RevA_SetTimeout((mxc_i2c_reva_regs_t *)i2c, timeout); -} - -unsigned int MXC_I2C_GetTimeout(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetTimeout((mxc_i2c_reva_regs_t *)i2c); -} - -int MXC_I2C_Recover(mxc_i2c_regs_t *i2c, unsigned int retries) -{ - return MXC_I2C_RevA_Recover(i2c, retries); -} - -/* ************************************************************************* */ -/* Transaction level functions */ -/* ************************************************************************* */ - -int MXC_I2C_MasterTransaction(mxc_i2c_req_t *req) -{ - return MXC_I2C_RevA_MasterTransaction(req); -} - -int MXC_I2C_MasterTransactionAsync(mxc_i2c_req_t *req) -{ - return MXC_I2C_RevA_MasterTransactionAsync(req); -} - -int MXC_I2C_MasterTransactionDMA(mxc_i2c_req_t *req) -{ - return MXC_I2C_RevA_MasterTransactionDMA(req); -} - -int MXC_I2C_SlaveTransaction(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback) -{ - return MXC_I2C_RevA_SlaveTransaction(i2c, callback, interruptCheck); -} - -int MXC_I2C_SlaveTransactionAsync(mxc_i2c_regs_t *i2c, mxc_i2c_slave_handler_t callback) -{ - return MXC_I2C_RevA_SlaveTransactionAsync(i2c, callback, interruptCheck); -} - -int MXC_I2C_SetRXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes) -{ - return MXC_I2C_RevA_SetRXThreshold(i2c, numBytes); -} - -unsigned int MXC_I2C_GetRXThreshold(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetRXThreshold(i2c); -} - -int MXC_I2C_SetTXThreshold(mxc_i2c_regs_t *i2c, unsigned int numBytes) -{ - return MXC_I2C_RevA_SetTXThreshold(i2c, numBytes); -} - -unsigned int MXC_I2C_GetTXThreshold(mxc_i2c_regs_t *i2c) -{ - return MXC_I2C_RevA_GetTXThreshold(i2c); -} - -void MXC_I2C_AsyncStop(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_AsyncStop((mxc_i2c_reva_regs_t *)i2c); -} - -void MXC_I2C_AbortAsync(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_AbortAsync((mxc_i2c_reva_regs_t *)i2c); -} - -void MXC_I2C_AsyncHandler(mxc_i2c_regs_t *i2c) -{ - MXC_I2C_RevA_AsyncHandler(i2c, interruptCheck); -} - -void MXC_I2C_DMACallback(int ch, int error) -{ - MXC_I2C_RevA_DMACallback(ch, error); -} diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me17.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me17.c index fce606665f..e82437b0a2 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me17.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me17.c @@ -102,7 +102,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -146,6 +146,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -193,30 +263,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - - case 2: - config.reqsel = MXC_DMA_REQUEST_I2C2RX; - break; - - default: - return E_BAD_PARAM; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -232,30 +280,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - - case 2: - config.reqsel = MXC_DMA_REQUEST_I2C2TX; - break; - - default: - return E_BAD_PARAM; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me18.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me18.c index 1c9e862a26..5c7bebd0b2 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me18.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me18.c @@ -102,7 +102,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -146,6 +146,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -193,23 +263,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -225,23 +280,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, - (mxc_i2c_reva_dma_complete_cb_t)callback, config, MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me21.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me21.c index a0471e7d65..fdef823a00 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me21.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me21.c @@ -158,7 +158,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -202,6 +202,76 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + case 2: + txReqSel = MXC_DMA_REQUEST_I2C2TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + case 2: + rxReqSel = MXC_DMA_REQUEST_I2C2RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -249,23 +319,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -281,23 +336,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_me55.c b/Libraries/PeriphDrivers/Source/I2C/i2c_me55.c index e358184523..5d065bb85b 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_me55.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_me55.c @@ -90,7 +90,7 @@ int MXC_I2C_Shutdown(mxc_i2c_regs_t *i2c) return E_NO_DEVICE; } - return E_NO_ERROR; + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); } int MXC_I2C_Reset(mxc_i2c_regs_t *i2c) @@ -132,6 +132,68 @@ int MXC_I2C_GetClockStretching(mxc_i2c_regs_t *i2c) return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); } +int MXC_I2C_DMA_Init(mxc_i2c_regs_t *i2c, mxc_dma_regs_t *dma, bool use_dma_tx, bool use_dma_rx) +{ + return MXC_I2C_RevA_DMA_Init((mxc_i2c_reva_regs_t *)i2c, (mxc_dma_reva_regs_t *)dma, use_dma_tx, + use_dma_rx); +} + +int MXC_I2C_DMA_GetTXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetTXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_GetRXChannel(mxc_i2c_regs_t *i2c) +{ + return MXC_I2C_RevA_DMA_GetRXChannel((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_DMA_SetRequestSelect(mxc_i2c_regs_t *i2c, uint8_t *txData, uint8_t *rxData) +{ + int i2cNum; + int txReqSel = -1; + int rxReqSel = -1; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (txData != NULL) { + switch (i2cNum) { + case 0: + txReqSel = MXC_DMA_REQUEST_I2C0TX; + break; + + case 1: + txReqSel = MXC_DMA_REQUEST_I2C1TX; + break; + + default: + return E_BAD_PARAM; + } + } + + if (rxData != NULL) { + switch (i2cNum) { + case 0: + rxReqSel = MXC_DMA_REQUEST_I2C0RX; + break; + + case 1: + rxReqSel = MXC_DMA_REQUEST_I2C1RX; + break; + + default: + return E_BAD_PARAM; + } + } + + return MXC_I2C_RevA_DMA_SetRequestSelect((mxc_i2c_reva_regs_t *)i2c, + (mxc_dma_reva_regs_t *)MXC_DMA, txReqSel, rxReqSel); +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -179,22 +241,8 @@ int MXC_I2C_ReadRXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsig int MXC_I2C_ReadRXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0RX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1RX; - break; - } - - return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetRXFIFOAvailable(mxc_i2c_regs_t *i2c) @@ -210,21 +258,8 @@ int MXC_I2C_WriteTXFIFO(mxc_i2c_regs_t *i2c, volatile unsigned char *bytes, unsi int MXC_I2C_WriteTXFIFODMA(mxc_i2c_regs_t *i2c, unsigned char *bytes, unsigned int len, mxc_i2c_dma_complete_cb_t callback) { - uint8_t i2cNum; - mxc_dma_config_t config; - i2cNum = MXC_I2C_GET_IDX(i2c); - - switch (i2cNum) { - case 0: - config.reqsel = MXC_DMA_REQUEST_I2C0TX; - break; - - case 1: - config.reqsel = MXC_DMA_REQUEST_I2C1TX; - break; - } - return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, callback, config, - MXC_DMA); + // The callback parameter was previously unused but keeping it for backwards-compatibility. + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, MXC_DMA); } int MXC_I2C_GetTXFIFOAvailable(mxc_i2c_regs_t *i2c) diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_reva.c b/Libraries/PeriphDrivers/Source/I2C/i2c_reva.c index 0e94286cdf..55554a788b 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_reva.c +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_reva.c @@ -34,6 +34,7 @@ #include #include #include +#include #include "mxc_device.h" #include "mxc_assert.h" #include "mxc_lock.h" @@ -43,6 +44,7 @@ #include "i2c.h" #include "i2c_reva.h" #include "dma.h" +#include "dma_reva.h" /* **** Variable Declaration **** */ typedef struct { @@ -52,6 +54,8 @@ typedef struct { int channelRx; // DMA channel for RX transaction volatile int writeDone; // Write done flag volatile int readDone; // Flag done flag + bool dma_initialized; // Check to see whether DMA was initialized + mxc_dma_reva_regs_t *dma; // Save DMA Instance } mxc_i2c_reva_req_state_t; static mxc_i2c_reva_req_state_t states[MXC_I2C_INSTANCES]; @@ -75,11 +79,14 @@ void MXC_I2C_RevA_SlaveAsyncHandler(mxc_i2c_reva_regs_t *i2c, mxc_i2c_reva_slave int MXC_I2C_RevA_Init(mxc_i2c_reva_regs_t *i2c, int masterMode, unsigned int slaveAddr) { int err; + int8_t i2cNum; if (i2c == NULL) { return E_NULL_PTR; } + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + if ((err = MXC_I2C_Recover((mxc_i2c_regs_t *)i2c, 16)) != E_NO_ERROR) { return err; } @@ -100,6 +107,13 @@ int MXC_I2C_RevA_Init(mxc_i2c_reva_regs_t *i2c, int masterMode, unsigned int sla states[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)].master = 1; } + // Prepare I2C instance state. + states[i2cNum].channelTx = E_NO_DEVICE; + states[i2cNum].channelRx = E_NO_DEVICE; + states[i2cNum].writeDone = 0; + states[i2cNum].readDone = 0; + states[i2cNum].dma_initialized = false; + return E_NO_ERROR; } @@ -132,7 +146,47 @@ int MXC_I2C_RevA_SetSlaveAddr(mxc_i2c_reva_regs_t *i2c, unsigned int slaveAddr, int MXC_I2C_RevA_Shutdown(mxc_i2c_reva_regs_t *i2c) { - return E_NOT_SUPPORTED; + int8_t i2cNum; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + i2c->ctrl = 0; + i2c->inten0 = 0; + i2c->inten1 = 0; + i2c->intfl0 = i2c->intfl0; + i2c->intfl1 = i2c->intfl1; + i2c->rxctrl0 = 0; + i2c->rxctrl1 = 0; + i2c->txctrl0 = 0; + i2c->txctrl1 = 0; + + states[i2cNum] = (const mxc_i2c_reva_req_state_t){ 0 }; + + MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c); + MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c); + + if (states[i2cNum].dma_initialized == true) { +#if TARGET_NUM == 32665 + MXC_DMA_DeInit((mxc_dma_regs_t *)(states[i2cNum].dma)); +#else + MXC_DMA_DeInit(); +#endif + // Release any acquired DMA channels. + if (states[i2cNum].channelTx >= 0) { + MXC_DMA_ReleaseChannel(states[i2cNum].channelTx); + states[i2cNum].channelTx = E_NO_DEVICE; + } + if (states[i2cNum].channelRx >= 0) { + MXC_DMA_ReleaseChannel(states[i2cNum].channelRx); + states[i2cNum].channelRx = E_NO_DEVICE; + } + } + + return E_NO_ERROR; } int MXC_I2C_RevA_SetFrequency(mxc_i2c_reva_regs_t *i2c, unsigned int hz) @@ -252,6 +306,161 @@ int MXC_I2C_RevA_GetClockStretching(mxc_i2c_reva_regs_t *i2c) return !((i2c->ctrl & MXC_F_I2C_REVA_CTRL_CLKSTR_DIS) >> MXC_F_I2C_REVA_CTRL_CLKSTR_DIS_POS); } +int MXC_I2C_RevA_DMA_Init(mxc_i2c_reva_regs_t *i2c, mxc_dma_reva_regs_t *dma, bool use_dma_tx, + bool use_dma_rx) +{ + int8_t i2cNum; + int8_t rxChannel; + int8_t txChannel; + + if (i2c == NULL || dma == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + if (states[i2cNum].dma_initialized == false) { +#if TARGET_NUM == 32665 + MXC_DMA_Init((mxc_dma_regs_t *)dma); +#else + MXC_DMA_Init(); +#endif + } + + // Release any acquire DMA TX channels before configuring. + if (states[i2cNum].channelTx != E_NO_DEVICE) { + MXC_DMA_ReleaseChannel(states[i2cNum].channelTx); + } + + // Release any acquire DMA RX channels before configuring. + if (states[i2cNum].channelRx != E_NO_DEVICE) { + MXC_DMA_ReleaseChannel(states[i2cNum].channelRx); + } + + // Set up I2C DMA TX. + if (use_dma_tx == true) { +#if TARGET_NUM == 32665 + txChannel = MXC_DMA_AcquireChannel((mxc_dma_regs_t *)dma); +#else + txChannel = MXC_DMA_AcquireChannel(); +#endif + + // Set Source and Destination Widths. + MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD, + (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_SRCWD_POS)); + MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD, + (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_DSTWD_POS)); + + // Set Source and Destination Increment. + MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCINC, + (1 << MXC_F_DMA_REVA_CTRL_SRCINC_POS)); + MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTINC, + (0 << MXC_F_DMA_REVA_CTRL_DSTINC_POS)); + + if (states[i2cNum].master) { + MXC_DMA_SetCallback(txChannel, MXC_I2C_RevA_DMACallback); + } else { + MXC_DMA_SetCallback(txChannel, NULL); + } + + MXC_DMA_EnableInt(txChannel); + MXC_DMA_SetChannelInterruptEn(txChannel, 0, 1); + + states[i2cNum].channelTx = txChannel; + } + + // Set up I2C DMA RX. + if (use_dma_rx == true) { +#if TARGET_NUM == 32665 + rxChannel = MXC_DMA_AcquireChannel((mxc_dma_regs_t *)dma); +#else + rxChannel = MXC_DMA_AcquireChannel(); +#endif + + // Set Source and Destination Widths. + MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCWD, + (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_SRCWD_POS)); + MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTWD, + (MXC_DMA_WIDTH_BYTE << MXC_F_DMA_REVA_CTRL_DSTWD_POS)); + + // Set Source and Destination Increment. + MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_SRCINC, + (0 << MXC_F_DMA_REVA_CTRL_SRCINC_POS)); + MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_DSTINC, + (1 << MXC_F_DMA_REVA_CTRL_DSTINC_POS)); + + if (states[i2cNum].master) { + MXC_DMA_SetCallback(rxChannel, MXC_I2C_RevA_DMACallback); + } else { + MXC_DMA_SetCallback(rxChannel, NULL); + } + + MXC_DMA_EnableInt(rxChannel); + MXC_DMA_SetChannelInterruptEn(rxChannel, 0, 1); + + states[i2cNum].channelRx = rxChannel; + } + + states[i2cNum].dma_initialized = true; + states[i2cNum].dma = dma; + + return E_NO_ERROR; +} + +int MXC_I2C_RevA_DMA_GetTXChannel(mxc_i2c_reva_regs_t *i2c) +{ + int i2cNum; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + return states[i2cNum].channelTx; +} + +int MXC_I2C_RevA_DMA_GetRXChannel(mxc_i2c_reva_regs_t *i2c) +{ + int i2cNum; + + if (i2c == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + return states[i2cNum].channelRx; +} + +int MXC_I2C_RevA_DMA_SetRequestSelect(mxc_i2c_reva_regs_t *i2c, mxc_dma_reva_regs_t *dma, + uint32_t txReqSel, uint32_t rxReqSel) +{ + int i2cNum; + uint32_t txChannel; + uint32_t rxChannel; + + if (i2c == NULL || dma == NULL) { + return E_NULL_PTR; + } + + i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + + txChannel = states[i2cNum].channelTx; + rxChannel = states[i2cNum].channelRx; + + // This function will overwrite the current DMA TX/RX Request Selects. + if (txReqSel != -1) { + MXC_SETFIELD(dma->ch[txChannel].ctrl, MXC_F_DMA_REVA_CTRL_REQUEST, txReqSel); + } + + if (rxReqSel != -1) { + MXC_SETFIELD(dma->ch[rxChannel].ctrl, MXC_F_DMA_REVA_CTRL_REQUEST, rxReqSel); + } + + return E_NO_ERROR; +} + /* ************************************************************************* */ /* Low-level functions */ /* ************************************************************************* */ @@ -420,11 +629,9 @@ int MXC_I2C_RevA_ReadRXFIFO(mxc_i2c_reva_regs_t *i2c, volatile unsigned char *by } int MXC_I2C_RevA_ReadRXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int len, - mxc_i2c_reva_dma_complete_cb_t callback, mxc_dma_config_t config, mxc_dma_regs_t *dma) { uint8_t i2cNum; - uint8_t channel; mxc_dma_srcdst_t srcdst; if ((i2c == NULL) || (bytes == NULL)) { @@ -433,37 +640,17 @@ int MXC_I2C_RevA_ReadRXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, u i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); -#if TARGET_NUM == 32665 - channel = MXC_DMA_AcquireChannel(dma); -#else - channel = MXC_DMA_AcquireChannel(); -#endif - - config.ch = channel; - - config.srcwd = MXC_DMA_WIDTH_BYTE; - config.dstwd = MXC_DMA_WIDTH_BYTE; - - config.srcinc_en = 0; - config.dstinc_en = 1; + if (states[i2cNum].channelRx == E_NO_DEVICE) { + return E_BAD_STATE; + } - srcdst.ch = channel; + srcdst.ch = states[i2cNum].channelRx; srcdst.dest = bytes; srcdst.len = len; - states[i2cNum].channelRx = channel; - MXC_DMA_ConfigChannel(config, srcdst); + MXC_DMA_SetSrcDst(srcdst); - if (states[i2cNum].master) { - MXC_DMA_SetCallback(channel, MXC_I2C_RevA_DMACallback); - } else { - MXC_DMA_SetCallback(channel, NULL); - } - - MXC_DMA_EnableInt(channel); - MXC_DMA_Start(channel); - //MXC_DMA->ch[channel].cfg |= MXC_F_DMA_CFG_CTZIEN; - MXC_DMA_SetChannelInterruptEn(channel, 0, 1); + MXC_DMA_Start(states[i2cNum].channelRx); i2c->dma |= MXC_F_I2C_REVA_DMA_RX_EN; return E_NO_ERROR; @@ -495,11 +682,9 @@ int MXC_I2C_RevA_WriteTXFIFO(mxc_i2c_reva_regs_t *i2c, volatile unsigned char *b } int MXC_I2C_RevA_WriteTXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int len, - mxc_i2c_reva_dma_complete_cb_t callback, mxc_dma_config_t config, mxc_dma_regs_t *dma) { - uint8_t i2cNum; - uint8_t channel; + int8_t i2cNum; mxc_dma_srcdst_t srcdst; if ((i2c == NULL) || (bytes == NULL)) { @@ -510,37 +695,17 @@ int MXC_I2C_RevA_WriteTXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, i2c->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_START; -#if TARGET_NUM == 32665 - channel = MXC_DMA_AcquireChannel(dma); -#else - channel = MXC_DMA_AcquireChannel(); -#endif - - config.ch = channel; - - config.srcwd = MXC_DMA_WIDTH_BYTE; - config.dstwd = MXC_DMA_WIDTH_BYTE; - - config.srcinc_en = 1; - config.dstinc_en = 0; + if (states[i2cNum].channelTx == E_NO_DEVICE) { + return E_BAD_STATE; + } - srcdst.ch = channel; + srcdst.ch = states[i2cNum].channelTx; srcdst.source = bytes; srcdst.len = len; - states[i2cNum].channelTx = channel; - MXC_DMA_ConfigChannel(config, srcdst); + MXC_DMA_SetSrcDst(srcdst); - if (states[i2cNum].master) { - MXC_DMA_SetCallback(channel, MXC_I2C_RevA_DMACallback); - } else { - MXC_DMA_SetCallback(channel, NULL); - } - - MXC_DMA_EnableInt(channel); - MXC_DMA_Start(channel); - // MXC_DMA->ch[channel].cfg |= MXC_F_DMA_CFG_CTZIEN; - MXC_DMA_SetChannelInterruptEn(channel, 0, 1); + MXC_DMA_Start(states[i2cNum].channelTx); i2c->dma |= MXC_F_I2C_REVA_DMA_TX_EN; return E_NO_ERROR; @@ -898,7 +1063,8 @@ int MXC_I2C_RevA_MasterTransactionAsync(mxc_i2c_reva_req_t *req) int MXC_I2C_RevA_MasterTransactionDMA(mxc_i2c_reva_req_t *req, mxc_dma_regs_t *dma) { - int i2cNum; + int error; + int8_t i2cNum; mxc_i2c_reva_regs_t *i2c = req->i2c; // Save off pointer for faster access i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); @@ -928,15 +1094,21 @@ int MXC_I2C_RevA_MasterTransactionDMA(mxc_i2c_reva_req_t *req, mxc_dma_regs_t *d MXC_I2C_SetRXThreshold((mxc_i2c_regs_t *)i2c, 1); states[i2cNum].req = req; + states[i2cNum].writeDone = 0; + states[i2cNum].readDone = 0; + + // If MXC_I2C_DMA_Init(...) was not already called, then configure both DMA TX/RXchannels by default. + if (states[i2cNum].dma_initialized == false) { + error = MXC_I2C_DMA_Init((mxc_i2c_regs_t *)i2c, (mxc_dma_regs_t *)dma, true, true); + if (error != E_NO_ERROR) { + return error; + } + } - states[i2cNum].channelTx = 0xFF; - states[i2cNum].channelRx = 0xFF; - -#if TARGET_NUM == 32665 - MXC_DMA_Init(dma); -#else - MXC_DMA_Init(); -#endif + error = MXC_I2C_DMA_SetRequestSelect((mxc_i2c_regs_t *)i2c, req->tx_buf, req->rx_buf); + if (error != E_NO_ERROR) { + return error; + } //tx if ((req->tx_buf != NULL) && !(states[i2cNum].writeDone)) { @@ -953,7 +1125,7 @@ int MXC_I2C_RevA_MasterTransactionDMA(mxc_i2c_reva_req_t *req, mxc_dma_regs_t *d if (req->rx_buf != NULL) { while (states[i2cNum].writeDone != 1) {} - //Ensure DMA transmit has finished before attempting to receive + //Ensure DMA transmission has finished before attempting to receive if ((states[i2cNum].writeDone) && (!states[i2cNum].readDone)) { if (req->rx_len > MXC_I2C_REVA_MAX_FIFO_TRANSACTION) { @@ -998,9 +1170,6 @@ void MXC_I2C_RevA_DMACallback(int ch, int error) (temp_req->i2c)->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP; } - MXC_DMA_ReleaseChannel(states[i].channelRx); - MXC_DMA_ReleaseChannel(states[i].channelTx); - // Callback if not NULL if (temp_req->callback != NULL) { temp_req->callback(temp_req, E_NO_ERROR); @@ -1018,9 +1187,6 @@ void MXC_I2C_RevA_DMACallback(int ch, int error) (temp_req->i2c)->mstctrl |= MXC_F_I2C_REVA_MSTCTRL_STOP; } - MXC_DMA_ReleaseChannel(states[i].channelRx); - MXC_DMA_ReleaseChannel(states[i].channelTx); - // Callback if not NULL if (temp_req->callback != NULL) { temp_req->callback(temp_req, E_NO_ERROR); diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_reva.h b/Libraries/PeriphDrivers/Source/I2C/i2c_reva.h index 74080f4bc3..1952bbbbcf 100644 --- a/Libraries/PeriphDrivers/Source/I2C/i2c_reva.h +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_reva.h @@ -45,6 +45,7 @@ #include "i2c_regs.h" #include "i2c_reva_regs.h" #include "dma.h" +#include "dma_reva_regs.h" /* **** Definitions **** */ #define MXC_I2C_REVA_MAX_ADDR_WIDTH 0x7F @@ -106,6 +107,12 @@ unsigned int MXC_I2C_RevA_GetFrequency(mxc_i2c_reva_regs_t *i2c); int MXC_I2C_RevA_ReadyForSleep(mxc_i2c_reva_regs_t *i2c); int MXC_I2C_RevA_SetClockStretching(mxc_i2c_reva_regs_t *i2c, int enable); int MXC_I2C_RevA_GetClockStretching(mxc_i2c_reva_regs_t *i2c); +int MXC_I2C_RevA_DMA_Init(mxc_i2c_reva_regs_t *i2c, mxc_dma_reva_regs_t *dma, bool use_dma_tx, + bool use_dma_rx); +int MXC_I2C_RevA_DMA_GetTXChannel(mxc_i2c_reva_regs_t *i2c); +int MXC_I2C_RevA_DMA_GetRXChannel(mxc_i2c_reva_regs_t *i2c); +int MXC_I2C_RevA_DMA_SetRequestSelect(mxc_i2c_reva_regs_t *i2c, mxc_dma_reva_regs_t *dma, + uint32_t txReqSel, uint32_t rxReqSel); /* ************************************************************************* */ /* Low-level functions */ @@ -121,13 +128,11 @@ int MXC_I2C_RevA_Read(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned i int MXC_I2C_RevA_ReadRXFIFO(mxc_i2c_reva_regs_t *i2c, volatile unsigned char *bytes, unsigned int len); int MXC_I2C_RevA_ReadRXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int len, - mxc_i2c_reva_dma_complete_cb_t callback, mxc_dma_config_t config, mxc_dma_regs_t *dma); int MXC_I2C_RevA_GetRXFIFOAvailable(mxc_i2c_reva_regs_t *i2c); int MXC_I2C_RevA_WriteTXFIFO(mxc_i2c_reva_regs_t *i2c, volatile unsigned char *bytes, unsigned int len); int MXC_I2C_RevA_WriteTXFIFODMA(mxc_i2c_reva_regs_t *i2c, unsigned char *bytes, unsigned int len, - mxc_i2c_reva_dma_complete_cb_t callback, mxc_dma_config_t config, mxc_dma_regs_t *dma); int MXC_I2C_RevA_GetTXFIFOAvailable(mxc_i2c_reva_regs_t *i2c); void MXC_I2C_RevA_ClearRXFIFO(mxc_i2c_reva_regs_t *i2c); diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_revb.c b/Libraries/PeriphDrivers/Source/I2C/i2c_revb.c new file mode 100644 index 0000000000..ca8acc6165 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_revb.c @@ -0,0 +1,456 @@ +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ + +#include +#include +#include +#include "mxc_errors.h" +#include "mxc_delay.h" +#include "mxc_assert.h" +#include "mxc_lock.h" +#include "mxc_sys.h" +#include "i2c_revb.h" +#include "i2c_reva.h" + +/* **** Definitions **** */ + +/* **** Variable Declaration **** */ + +// Saves the state of the non-blocking requests +typedef struct { + mxc_i2c_revb_req_t *req; + int master; // 1 for Master, 0 for slave + int channelTx; // DMA channel for TX transaction + int channelRx; // DMA channel for RX transaction + int writeDone; // Write done flag + int readDone; // Flag done flag +} mxc_i2c_revb_req_state_t; + +/* ************************************************************************* */ +/* Control/Configuration functions */ +/* ************************************************************************* */ + +int MXC_I2C_RevB_Init(mxc_i2c_revb_regs_t *i2c, int masterMode, unsigned int slaveAddr) +{ + return MXC_I2C_RevA_Init((mxc_i2c_reva_regs_t *)i2c, masterMode, slaveAddr); +} + +int MXC_I2C_RevB_SetSlaveAddr(mxc_i2c_revb_regs_t *i2c, unsigned int slaveAddr, int idx) +{ + if (i2c == NULL || slaveAddr > MXC_F_I2C_REVB_SLV_ADDR_SLA || idx != 0) { + return E_BAD_PARAM; + } + + i2c->slv_addr = 0; + + if (slaveAddr > MXC_I2C_REVB_MAX_ADDR_WIDTH) { + i2c->slv_addr |= MXC_S_I2C_REVB_SLV_ADDR_EA_10BIT_ADDR; + } + + i2c->slv_addr |= slaveAddr & MXC_F_I2C_REVB_SLV_ADDR_SLA; + + return E_NO_ERROR; +} + +int MXC_I2C_RevB_Shutdown(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_Shutdown((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_SetFrequency(mxc_i2c_revb_regs_t *i2c, unsigned int hz) +{ + return MXC_I2C_RevA_SetFrequency((mxc_i2c_reva_regs_t *)i2c, hz); +} + +unsigned int MXC_I2C_RevB_GetFrequency(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetFrequency((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_ReadyForSleep(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_ReadyForSleep((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_SetClockStretching(mxc_i2c_revb_regs_t *i2c, int enable) +{ + return MXC_I2C_RevA_SetClockStretching((mxc_i2c_reva_regs_t *)i2c, enable); +} + +int MXC_I2C_RevB_GetClockStretching(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetClockStretching((mxc_i2c_reva_regs_t *)i2c); +} + +/* ************************************************************************* */ +/* Low-level functions */ +/* ************************************************************************* */ + +int MXC_I2C_RevB_Start(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_Start((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_Stop(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_Stop((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_WriteByte(mxc_i2c_revb_regs_t *i2c, unsigned char byte) +{ + return MXC_I2C_RevA_WriteByte((mxc_i2c_reva_regs_t *)i2c, byte); +} + +int MXC_I2C_RevB_ReadByte(mxc_i2c_revb_regs_t *i2c, unsigned char *byte, int ack) +{ + return MXC_I2C_RevA_ReadByte((mxc_i2c_reva_regs_t *)i2c, byte, ack); +} + +int MXC_I2C_RevB_ReadByteInteractive(mxc_i2c_revb_regs_t *i2c, unsigned char *byte, + mxc_i2c_revb_getAck_t getAck) +{ + return MXC_I2C_RevA_ReadByteInteractive((mxc_i2c_reva_regs_t *)i2c, byte, + (mxc_i2c_reva_getAck_t)getAck); +} + +int MXC_I2C_RevB_Write(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int *len) +{ + return MXC_I2C_RevA_Write((mxc_i2c_reva_regs_t *)i2c, bytes, len); +} + +int MXC_I2C_RevB_Read(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack) +{ + return MXC_I2C_RevA_Read((mxc_i2c_reva_regs_t *)i2c, bytes, len, ack); +} + +int MXC_I2C_RevB_ReadRXFIFO(mxc_i2c_revb_regs_t *i2c, volatile unsigned char *bytes, + unsigned int len) +{ + return MXC_I2C_RevA_ReadRXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len); +} + +int MXC_I2C_RevB_ReadRXFIFODMA(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int len, + mxc_dma_regs_t *dma) +{ + return MXC_I2C_RevA_ReadRXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, dma); +} + +int MXC_I2C_RevB_GetRXFIFOAvailable(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetRXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_WriteTXFIFO(mxc_i2c_revb_regs_t *i2c, volatile unsigned char *bytes, + unsigned int len) +{ + return MXC_I2C_RevA_WriteTXFIFO((mxc_i2c_reva_regs_t *)i2c, bytes, len); +} + +int MXC_I2C_RevB_WriteTXFIFODMA(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int len, + mxc_dma_regs_t *dma) +{ + return MXC_I2C_RevA_WriteTXFIFODMA((mxc_i2c_reva_regs_t *)i2c, bytes, len, dma); +} + +int MXC_I2C_RevB_GetTXFIFOAvailable(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetTXFIFOAvailable((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_ClearRXFIFO(mxc_i2c_revb_regs_t *i2c) +{ + MXC_I2C_RevA_ClearRXFIFO((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_ClearTXFIFO(mxc_i2c_revb_regs_t *i2c) +{ + MXC_I2C_RevA_ClearTXFIFO((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_GetFlags(mxc_i2c_revb_regs_t *i2c, unsigned int *flags0, unsigned int *flags1) +{ + return MXC_I2C_RevA_GetFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_RevB_ClearFlags(mxc_i2c_revb_regs_t *i2c, unsigned int flags0, unsigned int flags1) +{ + MXC_I2C_RevA_ClearFlags((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_RevB_EnableInt(mxc_i2c_revb_regs_t *i2c, unsigned int flags0, unsigned int flags1) +{ + MXC_I2C_RevA_EnableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_RevB_DisableInt(mxc_i2c_revb_regs_t *i2c, unsigned int flags0, unsigned int flags1) +{ + MXC_I2C_RevA_DisableInt((mxc_i2c_reva_regs_t *)i2c, flags0, flags1); +} + +void MXC_I2C_RevB_EnablePreload(mxc_i2c_revb_regs_t *i2c) +{ + MXC_I2C_RevA_EnablePreload((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_DisablePreload(mxc_i2c_revb_regs_t *i2c) +{ + MXC_I2C_RevA_DisablePreload((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_EnableGeneralCall(mxc_i2c_revb_regs_t *i2c) +{ + i2c->ctrl0 |= MXC_F_I2C_REVB_CTRL0_GCEN; +} + +void MXC_I2C_RevB_DisableGeneralCall(mxc_i2c_revb_regs_t *i2c) +{ + i2c->ctrl0 &= ~MXC_F_I2C_REVB_CTRL0_GCEN; +} + +void MXC_I2C_RevB_SetTimeout(mxc_i2c_revb_regs_t *i2c, unsigned int timeout) +{ + MXC_I2C_RevA_SetTimeout((mxc_i2c_reva_regs_t *)i2c, timeout); +} + +unsigned int MXC_I2C_RevB_GetTimeout(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetTimeout((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_Recover(mxc_i2c_revb_regs_t *i2c, unsigned int retries) +{ + return MXC_I2C_RevA_Recover((mxc_i2c_reva_regs_t *)i2c, retries); +} + +/* ************************************************************************* */ +/* Transaction level functions */ +/* ************************************************************************* */ + +int MXC_I2C_RevB_MasterTransaction(mxc_i2c_revb_req_t *req) +{ + return MXC_I2C_RevA_MasterTransaction((mxc_i2c_reva_req_t *)req); +} + +int MXC_I2C_RevB_MasterTransactionAsync(mxc_i2c_revb_req_t *req) +{ + return MXC_I2C_RevA_MasterTransactionAsync((mxc_i2c_reva_req_t *)req); +} + +int MXC_I2C_RevB_MasterTransactionDMA(mxc_i2c_revb_req_t *req, mxc_dma_regs_t *dma) +{ + return MXC_I2C_RevA_MasterTransactionDMA((mxc_i2c_reva_req_t *)req, dma); +} + +int MXC_I2C_RevB_SlaveTransaction(mxc_i2c_revb_regs_t *i2c, mxc_i2c_revb_slave_handler_t callback, + uint32_t interruptCheck) +{ + return MXC_I2C_RevA_SlaveTransaction((mxc_i2c_reva_regs_t *)i2c, + (mxc_i2c_reva_slave_handler_t)callback, interruptCheck); +} + +int MXC_I2C_RevB_SlaveTransactionAsync(mxc_i2c_revb_regs_t *i2c, + mxc_i2c_revb_slave_handler_t callback, + uint32_t interruptCheck) +{ + return MXC_I2C_RevA_SlaveTransactionAsync( + (mxc_i2c_reva_regs_t *)i2c, (mxc_i2c_reva_slave_handler_t)callback, interruptCheck); +} + +int MXC_I2C_RevB_SetRXThreshold(mxc_i2c_revb_regs_t *i2c, unsigned int numBytes) +{ + return MXC_I2C_RevA_SetRXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes); +} + +unsigned int MXC_I2C_RevB_GetRXThreshold(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetRXThreshold((mxc_i2c_reva_regs_t *)i2c); +} + +int MXC_I2C_RevB_SetTXThreshold(mxc_i2c_revb_regs_t *i2c, unsigned int numBytes) +{ + return MXC_I2C_RevA_SetTXThreshold((mxc_i2c_reva_regs_t *)i2c, numBytes); +} + +unsigned int MXC_I2C_RevB_GetTXThreshold(mxc_i2c_revb_regs_t *i2c) +{ + return MXC_I2C_RevA_GetTXThreshold((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_AsyncCallback(mxc_i2c_revb_regs_t *i2c, int retVal) +{ + MXC_I2C_RevA_AsyncCallback((mxc_i2c_reva_regs_t *)i2c, retVal); +} + +void MXC_I2C_RevB_AsyncStop(mxc_i2c_revb_regs_t *i2c) +{ + MXC_I2C_RevA_AsyncStop((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_AbortAsync(mxc_i2c_revb_regs_t *i2c) +{ + MXC_I2C_RevA_AbortAsync((mxc_i2c_reva_regs_t *)i2c); +} + +void MXC_I2C_RevB_MasterAsyncHandler(int i2cNum) +{ + MXC_I2C_RevA_MasterAsyncHandler(i2cNum); +} + +unsigned int MXC_I2C_RevB_SlaveAsyncHandler(mxc_i2c_revb_regs_t *i2c, + mxc_i2c_revb_slave_handler_t callback, + unsigned int interruptEnables, int *retVal) +{ + *retVal = E_NO_ERROR; + + // Callback called on + // Slave Address Match (distinguish read/write) + // RX Threshold + // TX Threshold + // Done + // TX Underflow + // RX Overflow + // + // Event Codes + // I2C_EVT_MASTER_WR + // I2C_EVT_MASTER_RD + // I2C_EVT_RX_THRESH + // I2C_EVT_TX_THRESH + // I2C_EVT_TRANS_COMP + // I2C_EVT_UNDERFLOW + // I2C_EVT_OVERFLOW + if (!(interruptEnables & (MXC_F_I2C_REVB_INT_FL0_AMI))) { + // The STOPERR/STARTERR interrupt that's enabled here could fire before we are addressed + // (fires anytime a stop/start is detected out of sequence). + if (i2c->int_fl0 & MXC_I2C_REVB_ERROR) { + *retVal = E_COMM_ERR; + callback(i2c, MXC_I2C_REVB_EVT_TRANS_COMP, retVal); + MXC_I2C_ClearFlags((mxc_i2c_regs_t *)i2c, MXC_I2C_REVB_INTFL0_MASK, + MXC_I2C_REVB_INTFL1_MASK); // Clear all I2C Interrupts + MXC_I2C_ClearTXFIFO((mxc_i2c_regs_t *)i2c); + MXC_I2C_ClearRXFIFO((mxc_i2c_regs_t *)i2c); + interruptEnables = 0; + AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL; + } + + if (interruptEnables & (MXC_F_I2C_REVB_INT_FL0_RXTHI | MXC_F_I2C_REVB_INT_FL1_RXOFI)) { + if (i2c->int_fl0 & MXC_F_I2C_REVB_INT_FL0_RXTHI) { + callback(i2c, MXC_I2C_REVB_EVT_RX_THRESH, NULL); + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_RXTHI; + } + + if (i2c->int_fl1 & MXC_F_I2C_REVB_INT_FL1_RXOFI) { + callback(i2c, MXC_I2C_REVB_EVT_OVERFLOW, NULL); + i2c->int_fl1 = MXC_F_I2C_REVB_INT_FL1_RXOFI; + } + } + + if (interruptEnables & (MXC_F_I2C_REVB_INT_FL0_TXTHI | MXC_F_I2C_REVB_INT_FL1_TXUFI | + MXC_F_I2C_REVB_INT_FL0_TXLOI)) { + if (i2c->int_fl0 & MXC_F_I2C_REVB_INT_FL0_TXTHI) { + callback(i2c, MXC_I2C_REVB_EVT_TX_THRESH, NULL); + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_TXTHI; + } + + if (i2c->int_fl1 & MXC_F_I2C_REVB_INT_FL1_TXUFI) { + callback(i2c, MXC_I2C_REVB_EVT_UNDERFLOW, NULL); + i2c->int_fl1 = MXC_F_I2C_REVB_INT_FL1_TXUFI; + } + + if (i2c->int_fl0 & MXC_F_I2C_REVB_INT_FL0_TXLOI) { + *retVal = E_NO_ERROR; + callback(i2c, MXC_I2C_REVB_EVT_TRANS_COMP, retVal); + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_TXLOI; + interruptEnables = 0; + AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL; + } + } + + if (i2c->int_fl0 & MXC_F_I2C_REVB_INT_FL0_STOPI) { + *retVal = E_NO_ERROR; + callback(i2c, MXC_I2C_REVB_EVT_TRANS_COMP, retVal); + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_STOPI; + interruptEnables = 0; + AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL; + } + } + + if (i2c->int_fl0 & MXC_F_I2C_REVB_INT_FL0_AMI) { + if (i2c->ctrl0 & MXC_F_I2C_REVB_CTRL0_READ) { + callback(i2c, MXC_I2C_REVB_EVT_MASTER_RD, NULL); + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_AMI; + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_AMI; + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_TXLOI; + interruptEnables = MXC_F_I2C_REVB_INT_FL0_TXTHI | MXC_F_I2C_REVB_INT_FL1_TXUFI | + MXC_F_I2C_REVB_INT_FL0_TXLOI | MXC_I2C_REVB_ERROR; + } else { + callback(i2c, MXC_I2C_REVB_EVT_MASTER_WR, NULL); + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_AMI; + i2c->int_fl0 = MXC_F_I2C_REVB_INT_FL0_AMI; + interruptEnables = MXC_F_I2C_REVB_INT_FL0_RXTHI | MXC_F_I2C_REVB_INT_FL1_RXOFI | + MXC_I2C_REVB_ERROR; + } + } else if (i2c->int_fl0 & MXC_I2C_REVB_ERROR) { + *retVal = E_COMM_ERR; + callback(i2c, MXC_I2C_REVB_EVT_TRANS_COMP, retVal); + MXC_I2C_RevB_ClearFlags(i2c, MXC_I2C_REVB_INTFL0_MASK, + MXC_I2C_REVB_INTFL1_MASK); // clear all i2c interrupts + MXC_I2C_RevB_ClearTXFIFO(i2c); + MXC_I2C_RevB_ClearRXFIFO(i2c); + interruptEnables = 0; + AsyncRequests[MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c)] = NULL; + } + + return interruptEnables; +} + +void MXC_I2C_RevB_AsyncHandler(mxc_i2c_revb_regs_t *i2c, uint32_t interruptCheck) +{ + int i2cNum = MXC_I2C_GET_IDX((mxc_i2c_regs_t *)i2c); + int slaveRetVal; + + if (i2cNum < 0) { + return; + } + + if (i2c->ctrl0 & MXC_F_I2C_REVB_CTRL0_MST) { + MXC_I2C_RevB_MasterAsyncHandler(i2cNum); + } else { + mxc_i2c_revb_slave_handler_t callback = (mxc_i2c_revb_slave_handler_t)AsyncRequests[i2cNum]; + i2c->int_en0 = MXC_I2C_RevB_SlaveAsyncHandler(i2c, callback, i2c->int_en0, &slaveRetVal); + } +} + +void MXC_I2C_RevB_DMACallback(int ch, int error) +{ + MXC_I2C_RevA_DMACallback(ch, error); +} diff --git a/Libraries/PeriphDrivers/Source/I2C/i2c_revb.h b/Libraries/PeriphDrivers/Source/I2C/i2c_revb.h new file mode 100644 index 0000000000..2394d8f094 --- /dev/null +++ b/Libraries/PeriphDrivers/Source/I2C/i2c_revb.h @@ -0,0 +1,168 @@ +/** + * @file i2c_revb.h + * @brief Inter-integrated circuit (I2C_REVB) communications interface driver. + */ + +/****************************************************************************** + * Copyright (C) 2023 Maxim Integrated Products, Inc., 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 MAXIM INTEGRATED 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. + * + * Except as contained in this notice, the name of Maxim Integrated + * Products, Inc. shall not be used except as stated in the Maxim Integrated + * Products, Inc. Branding Policy. + * + * The mere transfer of this software does not imply any licenses + * of trade secrets, proprietary technology, copyrights, patents, + * trademarks, maskwork rights, or any other form of intellectual + * property whatsoever. Maxim Integrated Products, Inc. retains all + * ownership rights. + * + ******************************************************************************/ + +#ifndef LIBRARIES_PERIPHDRIVERS_SOURCE_I2C_I2C_REVB_H_ +#define LIBRARIES_PERIPHDRIVERS_SOURCE_I2C_I2C_REVB_H_ + +#include +#include "i2c.h" +#include "i2c_reva.h" +#include "i2c_revb_regs.h" +#include "mxc_sys.h" + +/* **** Definitions **** */ +#define MXC_I2C_REVB_MAX_ADDR_WIDTH 0x7F +#define MXC_I2C_REVB_STD_MODE 100000 +#define MXC_I2C_REVB_FAST_SPEED 400000 +#define MXC_I2C_REVB_FASTPLUS_SPEED 1000000 +#define MXC_I2C_REVB_HS_MODE 3400000 + +#define MXC_I2C_REVB_INTFL0_MASK 0x00FFFFFF +#define MXC_I2C_REVB_INTFL1_MASK 0x00000007 + +#define MXC_I2C_REVB_MAX_FIFO_TRANSACTION 256 + +#define MXC_I2C_REVB_ERROR \ + (MXC_F_I2C_REVB_INT_FL0_ARBERI | MXC_F_I2C_REVB_INT_FL0_TOERI | \ + MXC_F_I2C_REVB_INT_FL0_ADRERI | MXC_F_I2C_REVB_INT_FL0_DATAERI | \ + MXC_F_I2C_REVB_INT_FL0_DNRERI | MXC_F_I2C_REVB_INT_FL0_STRTERI | \ + MXC_F_I2C_REVB_INT_FL0_STOPERI) + +typedef struct _i2c_revb_req_t mxc_i2c_revb_req_t; +typedef int (*mxc_i2c_revb_getAck_t)(mxc_i2c_revb_regs_t *i2c, unsigned char byte); +typedef void (*mxc_i2c_revb_complete_cb_t)(mxc_i2c_revb_req_t *req, int result); +typedef void (*mxc_i2c_revb_dma_complete_cb_t)(int len, int result); +struct _i2c_revb_req_t { + mxc_i2c_revb_regs_t *i2c; + unsigned int addr; + unsigned char *tx_buf; + unsigned int tx_len; + unsigned char *rx_buf; + unsigned int rx_len; + int restart; + mxc_i2c_revb_complete_cb_t callback; +}; +typedef enum { + MXC_I2C_REVB_EVT_MASTER_WR, + MXC_I2C_REVB_EVT_MASTER_RD, + MXC_I2C_REVB_EVT_RX_THRESH, + MXC_I2C_REVB_EVT_TX_THRESH, + MXC_I2C_REVB_EVT_TRANS_COMP, + MXC_I2C_REVB_EVT_UNDERFLOW, + MXC_I2C_REVB_EVT_OVERFLOW, +} mxc_i2c_revb_slave_event_t; +typedef int (*mxc_i2c_revb_slave_handler_t)(mxc_i2c_revb_regs_t *i2c, + mxc_i2c_revb_slave_event_t event, void *data); +/* **** Variable Declaration **** */ + +/* **** Function Prototypes **** */ + +/* ************************************************************************* */ +/* Control/Configuration functions */ +/* ************************************************************************* */ +int MXC_I2C_RevB_Init(mxc_i2c_revb_regs_t *i2c, int masterMode, unsigned int slaveAddr); + +int MXC_I2C_RevB_SetSlaveAddr(mxc_i2c_revb_regs_t *i2c, unsigned int slaveAddr, int idx); +int MXC_I2C_RevB_Shutdown(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_SetFrequency(mxc_i2c_revb_regs_t *i2c, unsigned int hz); +unsigned int MXC_I2C_RevB_GetFrequency(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_ReadyForSleep(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_SetClockStretching(mxc_i2c_revb_regs_t *i2c, int enable); +int MXC_I2C_RevB_GetClockStretching(mxc_i2c_revb_regs_t *i2c); + +/* ************************************************************************* */ +/* Low-level functions */ +/* ************************************************************************* */ +int MXC_I2C_RevB_Start(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_Stop(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_WriteByte(mxc_i2c_revb_regs_t *i2c, unsigned char byte); +int MXC_I2C_RevB_ReadByte(mxc_i2c_revb_regs_t *i2c, unsigned char *byte, int ack); +int MXC_I2C_RevB_ReadByteInteractive(mxc_i2c_revb_regs_t *i2c, unsigned char *byte, + mxc_i2c_revb_getAck_t getAck); +int MXC_I2C_RevB_Write(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int *len); +int MXC_I2C_RevB_Read(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int *len, int ack); +int MXC_I2C_RevB_ReadRXFIFO(mxc_i2c_revb_regs_t *i2c, volatile unsigned char *bytes, + unsigned int len); +int MXC_I2C_RevB_ReadRXFIFODMA(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int len, + mxc_dma_regs_t *dma); +int MXC_I2C_RevB_GetRXFIFOAvailable(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_WriteTXFIFO(mxc_i2c_revb_regs_t *i2c, volatile unsigned char *bytes, + unsigned int len); +int MXC_I2C_RevB_WriteTXFIFODMA(mxc_i2c_revb_regs_t *i2c, unsigned char *bytes, unsigned int len, + mxc_dma_regs_t *dma); +int MXC_I2C_RevB_GetTXFIFOAvailable(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_ClearRXFIFO(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_ClearTXFIFO(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_GetFlags(mxc_i2c_revb_regs_t *i2c, unsigned int *flags0, unsigned int *flags1); +void MXC_I2C_RevB_ClearFlags(mxc_i2c_revb_regs_t *i2c, unsigned int flags0, unsigned int flags1); +void MXC_I2C_RevB_EnableInt(mxc_i2c_revb_regs_t *i2c, unsigned int flags0, unsigned int flags1); +void MXC_I2C_RevB_DisableInt(mxc_i2c_revb_regs_t *i2c, unsigned int flags0, unsigned int flags1); +void MXC_I2C_RevB_EnablePreload(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_DisablePreload(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_EnableGeneralCall(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_DisableGeneralCall(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_SetTimeout(mxc_i2c_revb_regs_t *i2c, unsigned int timeout); +unsigned int MXC_I2C_RevB_GetTimeout(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_Recover(mxc_i2c_revb_regs_t *i2c, unsigned int retries); + +/* ************************************************************************* */ +/* Transaction level functions */ +/* ************************************************************************* */ +int MXC_I2C_RevB_MasterTransaction(mxc_i2c_revb_req_t *req); +int MXC_I2C_RevB_MasterTransactionAsync(mxc_i2c_revb_req_t *req); +int MXC_I2C_RevB_MasterTransactionDMA(mxc_i2c_revb_req_t *req, mxc_dma_regs_t *dma); +int MXC_I2C_RevB_SlaveTransaction(mxc_i2c_revb_regs_t *i2c, mxc_i2c_revb_slave_handler_t callback, + uint32_t interruptCheck); +int MXC_I2C_RevB_SlaveTransactionAsync(mxc_i2c_revb_regs_t *i2c, + mxc_i2c_revb_slave_handler_t callback, + uint32_t interruptCheck); +int MXC_I2C_RevB_SetRXThreshold(mxc_i2c_revb_regs_t *i2c, unsigned int numBytes); +unsigned int MXC_I2C_RevB_GetRXThreshold(mxc_i2c_revb_regs_t *i2c); +int MXC_I2C_RevB_SetTXThreshold(mxc_i2c_revb_regs_t *i2c, unsigned int numBytes); +unsigned int MXC_I2C_RevB_GetTXThreshold(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_AsyncCallback(mxc_i2c_revb_regs_t *i2c, int retVal); +void MXC_I2C_RevB_AsyncStop(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_AbortAsync(mxc_i2c_revb_regs_t *i2c); +void MXC_I2C_RevB_MasterAsyncHandler(int i2cNum); +unsigned int MXC_I2C_RevB_SlaveAsyncHandler(mxc_i2c_revb_regs_t *i2c, + mxc_i2c_revb_slave_handler_t callback, + unsigned int interruptEnables, int *retVal); +void MXC_I2C_RevB_AsyncHandler(mxc_i2c_revb_regs_t *i2c, uint32_t interruptCheck); +void MXC_I2C_RevB_DMACallback(int ch, int error); + +#endif // LIBRARIES_PERIPHDRIVERS_SOURCE_I2C_I2C_REVB_H_