defragster
Senior Member+
Changed time calc to ARM_DWT_CYCCNT - and did it without the add math:
Collected the prior versions above and the latest - not all return the same value - but pins here are floating.
Code:
3 :: 32
2 :: C0
1 :: C0
A :: C0
B :: 32
t3 result = 20002.035000 32
t2 result = 66674.343333 C0
t1 result = 55006.448333 C0
tA result = 55006.441667 C0
tB result = 23336.541667 32
Collected the prior versions above and the latest - not all return the same value - but pins here are floating.
Code:
#define IMXRT_GPIO6_DIRECT (*(volatile uint32_t *)0x42000000)
#define IMXRT_GPIO9_DIRECT (*(volatile uint32_t *)0x4200C000)
#define IMXRT_GPIO7_DIRECT (*(volatile uint32_t *)0x42004000)
// this can be done with a mask and 2 less shifts
//#define IO_BLOCK_A ((IMXRT_GPIO7_DIRECT << 29) >> 29)
//#define IO_BLOCK_B (((IMXRT_GPIO9_DIRECT >> 4) << 29) >> 26)
//#define IO_BLOCK_C (((IMXRT_GPIO6_DIRECT >> 16) << 28) >> 22)
//#define IO_BLOCK_D (((IMXRT_GPIO6_DIRECT >> 22) << 26) >> 16)
#define IO_BLOCK_A (IMXRT_GPIO7_DIRECT & 0b00000000000000000000000000000111)
#define IO_BLOCK_B ((IMXRT_GPIO9_DIRECT & 0b00000000000000000000000001110000) >> 1)
#define IO_BLOCK_C ((IMXRT_GPIO6_DIRECT & 0b00000000000011110000000000000000) >> 10)
#define IO_BLOCK_D ((IMXRT_GPIO6_DIRECT & 0b00001111110000000000000000000000) >> 12)
void setup() {
pinMode(2, INPUT);
pinMode(3, INPUT);
pinMode(4, INPUT);
pinMode(10, INPUT);
pinMode(11, INPUT);
pinMode(12, INPUT);
pinMode(17, INPUT);
pinMode(16, INPUT);
pinMode(22, INPUT);
pinMode(23, INPUT);
pinMode(20, INPUT);
pinMode(21, INPUT);
pinMode(19, INPUT);
pinMode(18, INPUT);
pinMode(14, INPUT);
pinMode(15, INPUT);
Serial.begin(115200);
while (!Serial && millis() < 4000 );
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
}
void loop() {
Serial.printf( "3 :: %X\n", test3() );
Serial.printf( "2 :: %X\n", test2() );
Serial.printf( "1 :: %X\n", test1() );
Serial.printf( "A :: %X\n", testA() );
Serial.printf( "B :: %X\n", testB() );
Serial.printf( "\n" );
delay(2000);
loopNot();
}
inline uint32_t testA() {
uint16_t data = IO_BLOCK_A | IO_BLOCK_B | IO_BLOCK_C | IO_BLOCK_D;
return data;
}
inline uint32_t testB() {
register uint32_t data = IMXRT_GPIO6_DIRECT >> 2;
asm volatile("bfi %0, %1, 12, 2" : "+r"(data) : "r"(data));
asm volatile("bfi %0, %1, 18, 2" : "+r"(data) : "r"(data >> 28));
return (data >> 10) & 0xffff;
}
inline uint32_t test1() {
return IO_BLOCK_A | IO_BLOCK_B | IO_BLOCK_C | IO_BLOCK_D;
}
inline uint32_t test2() {
uint32_t data = IMXRT_GPIO7_DIRECT & 0b00000000000000000000000000000111;
asm volatile("bfi %0, %1, 3, 3" : "+r"(data) : "r"(IMXRT_GPIO9_DIRECT >> 4));
asm volatile("bfi %0, %1, 6, 4" : "+r"(data) : "r"(IMXRT_GPIO6_DIRECT >> 16));
asm volatile("bfi %0, %1, 10, 6" : "+r"(data) : "r"(IMXRT_GPIO6_DIRECT >> 22));
return data;
}
#define IMXRT_GPIO6_DIRECT (*(volatile uint32_t *)0x42000000)
inline uint32_t test3()
{
register uint32_t data = IMXRT_GPIO6_DIRECT;
register uint32_t data2 = data >> 30;
register uint32_t data3 = data >> 2;
asm volatile("bfi %0, %1, 20, 2" : "+r"(data) : "r"(data2));
asm volatile("bfi %0, %1, 14, 2" : "+r"(data) : "r"(data3));
return (data >> 12) & 0xffff;
}
void loopNot()
{
long unsigned stime;
stime = ARM_DWT_CYCCNT;
for (register int i = 0; i < 1000000; ++i ) {
test3();
}
Serial.printf("t3 result = %f %X\n", 1000000.0 * (ARM_DWT_CYCCNT - stime) / F_CPU_ACTUAL, test3());
stime = ARM_DWT_CYCCNT;
for (register int i = 0; i < 1000000; ++i ) {
test2();
}
Serial.printf("t2 result = %f %X\n", 1000000.0 * (ARM_DWT_CYCCNT - stime) / F_CPU_ACTUAL, test2());
stime = ARM_DWT_CYCCNT;
for (register int i = 0; i < 1000000; ++i ) {
test1();
}
Serial.printf("t1 result = %f %X\n", 1000000.0 * (ARM_DWT_CYCCNT - stime) / F_CPU_ACTUAL, test1());
stime = ARM_DWT_CYCCNT;
for (register int i = 0; i < 1000000; ++i ) {
testA();
}
Serial.printf("tA result = %f %X\n", 1000000.0 * (ARM_DWT_CYCCNT - stime) / F_CPU_ACTUAL, testA());
stime = ARM_DWT_CYCCNT;
for (register int i = 0; i < 1000000; ++i ) {
testB();
}
Serial.printf("tB result = %f %X\n", 1000000.0 * (ARM_DWT_CYCCNT - stime) / F_CPU_ACTUAL, testB());
delay(10000);
}