Hi,
I have some troubles using TWI easy DMA. I set EASY_DMA flag to 1, but I can't see any results in my performance tests. Can anyone explain me the required steps?
Thanks!
Hi,
I have some troubles using TWI easy DMA. I set EASY_DMA flag to 1, but I can't see any results in my performance tests. Can anyone explain me the required steps?
Thanks!
In the nRF52 design, you have a set number of instances of various peripherals (SPI. TWI, UART, etc...) Each instance has a memory-mapped block of registers. Note however that there are a couple of possible overlaps:
- Different types of peripheral blocks can share the same instance -- for example, the register block at 0x40003000 can be configured to be either SPI or TWI.
- The same instance can be used for the same kind of peripheral but in either EasyDMA mode or programmed I/O mode.
How do you choose which mode is in use? It depends on the value written to the ENABLE register, which is typically at offset 0x500 within a given instance's register block.
For example, look at the Product Specification document for the nRF52840. Section "4.2.4 Instantiation" gives you an overview of all the peripheral blocks. You'll notice that register block at 0x40003000 can be configured for up to 6 different modes: SPI, SPIS, SPIM, TWI, TWIS and TWIM.
You can only have at most two instances of TWI configured at the same time: one at 0x40003000 and another at 0x40004000. The value written to the enable register, i.e. 0x40003500 and 0x40004500, tells you what mode it's set for.
How do you know the mode value? You have to look at the peripheral description for TWI, TWIS and TWIM. For example, section 6.29 describes TWI (the programmed I/O mode). You'll notice that section 6.29.8.5 documents two values for the ENABLE register: 0 to disable TWI, and 5 to enable TWI.
Now look at section 6.31, which is for TWIM (the EasyDMA master mode). Section 6.31.7.6 documents two values for the ENABLE register as well: 0 to disable TWIM and 6 to enable TWIM.
Note the difference: 5 is for TWI mode (programmed I/O) and 6 is for TWIM (EasyDMA). For TWIS mode, the value is 9. These values also show up in the nrf52xxx.h header files included in the SDK.
The meaning of many of the other registers in the block depends on which value you write. Remember: the same block is used for both modes, but the layout of the register table is different. (In TWI mode for example, the EasyDMA source address register doesn't exist.)
So if you want confirm if a given TWI instance is being used in programmed I/O mode or EasyDMA mode, add some code to read the value from the ENABLE register (0x40003500 for TWI0 and 0x40004500 for TWI1) and print it on the console (or else examine it using the debugger). If it says 5 then you're using programmed I/O mode, and if it says 6 then you're using EasyDMA mode. If it says 0, the instance is disabled. When you set the EASY_DMA flag in the example code, this controls which mechanism the example code uses to program the TWI instance, and you can detect that by checking what value is programmed into the ENABLE register.
Hi wpaul,
Did you mean to read ENABLE register through nrf_fstorage_t?
I did it, and I saw the value 6. Does it mean that I'm using Easy DMA for sure?
Thanks!
I don't know offhand if nrf_fstorage_t has a pointer to the TWI register window. The nrfxxx.h header files for each chip define special types for the register overlay structures and they also have macros to define the base addresses. You should be able to do something like:
printf ("enable register: %x\n", NRF_TWI0->ENABLE);
or
printf ("enable register: %x\n", NRF_TWIM0->ENABLE);
The NRF_TWI0 handle is for using the TWI instance in programmed I/O mode. NRF_TWIM0 should be used when the instance is in EasyDMA mode. Some of the registers are the same, e.g. ENABLE, so you'll get the same result regardless of which you choose, but many others are different, so for actual operation you need to use the right handle depending on the mode.
But yes, if you get back 6, that means the TWI instance is set for EasyDMA master mode.
As for measuring performance, be aware that the two major advantages to using EasyDMA are: 1) You can transmit a block of data at a once instead having to read/write a byte at a time, and 2) while the DMA engine is busy moving the data, the CPU can go off and do other things (i.e. parallelization). TWI/I2C isn't a very high speed interface, so it's possible that you can actually get reasonably good data transfer speed in either mode. So unless you measure very carefully you might not notice much difference. With programmed I/O you may see a little worse performance due to pauses between transmissions of individual bytes (this may be mitigated somewhat if the interface is designed with a FIFO). But using EasyDMA drastically reduces CPU usage.
I don't know offhand if nrf_fstorage_t has a pointer to the TWI register window. The nrfxxx.h header files for each chip define special types for the register overlay structures and they also have macros to define the base addresses. You should be able to do something like:
printf ("enable register: %x\n", NRF_TWI0->ENABLE);
or
printf ("enable register: %x\n", NRF_TWIM0->ENABLE);
The NRF_TWI0 handle is for using the TWI instance in programmed I/O mode. NRF_TWIM0 should be used when the instance is in EasyDMA mode. Some of the registers are the same, e.g. ENABLE, so you'll get the same result regardless of which you choose, but many others are different, so for actual operation you need to use the right handle depending on the mode.
But yes, if you get back 6, that means the TWI instance is set for EasyDMA master mode.
As for measuring performance, be aware that the two major advantages to using EasyDMA are: 1) You can transmit a block of data at a once instead having to read/write a byte at a time, and 2) while the DMA engine is busy moving the data, the CPU can go off and do other things (i.e. parallelization). TWI/I2C isn't a very high speed interface, so it's possible that you can actually get reasonably good data transfer speed in either mode. So unless you measure very carefully you might not notice much difference. With programmed I/O you may see a little worse performance due to pauses between transmissions of individual bytes (this may be mitigated somewhat if the interface is designed with a FIFO). But using EasyDMA drastically reduces CPU usage.