PDA

View Full Version : Anyone else programming with Microchip C30? (Bitwise operation)



Art
- 14th May 2015, 02:35
Hi Guys,

I’ve been porting my reusable code to C30 from BASIC/assembler with mixed results where speed is concerned.
Bitwise operation has always been clumsy in C. Below are two examples, one in asm, and one C,
that both rotate a ten byte array bitwise one place to the right.
Does anyone have a faster (not smaller) way in C?

There could be other areas I need to check such as LCD timings, etc.
dsPic is much faster, and I thought speed difference of the code would be compensated for by that.
Cheers, Art.



RotateRight ;bitwise rotate array
rrf HMK+0 ,F ;a faster way
rrf HMK+1 ,F ;
rrf HMK+2 ,F ;
rrf HMK+3 ,F ;
rrf HMK+4 ,F ;
rrf HMK+5 ,F ;
rrf HMK+6 ,F ;
rrf HMK+7 ,F ;
rrf HMK+8 ,F ;
rrf HMK+9 ,F ;
bcf HMK+0 ,7 ;preclear MSB
btfsc status ,C ;check carry bit
bsf HMK+0 ,7 ;set MSB
return ;or return




void rotateRight() {
temp = (HMK[9] << 7); // rotate HMK right once
HMK[9] = (HMK[8] << 7) | (HMK[9] >> 1);
HMK[8] = (HMK[7] << 7) | (HMK[8] >> 1);
HMK[7] = (HMK[6] << 7) | (HMK[7] >> 1);
HMK[6] = (HMK[5] << 7) | (HMK[6] >> 1);
HMK[5] = (HMK[4] << 7) | (HMK[5] >> 1);
HMK[4] = (HMK[3] << 7) | (HMK[4] >> 1);
HMK[3] = (HMK[2] << 7) | (HMK[3] >> 1);
HMK[2] = (HMK[1] << 7) | (HMK[2] >> 1);
HMK[1] = (HMK[0] << 7) | (HMK[1] >> 1);
HMK[0] = temp | (HMK[0] >> 1);
}

mackrackit
- 15th May 2015, 07:06
I do not have an answer for you, but I have been playing with MicroChip XC8 (free version). So far the speed and code size seem about the same for similar functions.

Compile time is much faster though. So other than cross platform abilities and add in trouble like you are having, I do not see much of a reason to switch from PBP. I know,,, the dsPic is the reason.
Is that the reason you are moving to "C"?

Art
- 15th May 2015, 08:44
In this case it looks like long LCD delays were the holdup which I didn’t notice until I tried graphics.
The compiled asm for the C above would be at least 3 times slower, and probably even worse,
but the speed of the dsPic more than compensates for that without any inline asm in the C code.

The reason I chose dsPic for the particular project was floating point math,
and the fact that I’d already ported the exact functions I wanted into the exact same dsPic a few years ago,
but that was a modification to someone else’s project rather than writing a chip myself.
I understand the trig PBP library exists, but that doesn’t make it the right tool for the particular job.

I wouldn’t call it a move, I have C projects in the App Store, etc. and used Borland C for Windows,
but I have made an effort to port just about everything I might reuse because I will want the dsPic to continue to be an option.
this routine above is for character LCD graphics, it’s a 50 byte array that gets bitwise rotated often, so speed is desirable.

My current enthusiasm for it is because I have only used 16F84, 16F628, 16F876, 16F877. That’s it... ever!! :D
so it’s like a whole new world as far as capability is concerned, rather than about a language.

richard
- 15th May 2015, 09:57
if you made the array from longs or ints does the c compiler make better code for bit rotation ? , you could always access the array as bytes via a union . just a thought

Art
- 15th May 2015, 11:05
The array is already bytes, either declared BYTE or unsigned char.
The problem with C is aside from port pin bits or their latch registers which appear to be specially accounted for,
you still need to apply a mask to bytes to change one bit, or look/ test for a bit.
Something like asm “shift right with carry” does not seem to exist unless you went back to inline assembler in the C.
But I still think in every case the dsPic still wins because it’s running so much faster than the 20MHz/4 that I’m used to.

I’ve run into this way before now... C does suck at that.
https://www.youtube.com/watch?v=HUx9w4gyQ5c
Apologies, I wanted the picture to be interesting, but not thrown off YouTube.
You can see a large patch of the same colour because it’s a block cipher.
I had to apply a huge Xor mask to every image before hand to cover that.

richard
- 15th May 2015, 12:41
nice pic , what I was really think is , will a I bit shift on a long execute quicker than doing a 1 bit shift through 4 bytes

Demon
- 15th May 2015, 13:34
Art,why not give an 18F a try at 64MHz? Wouldn't that be a bit faster than 20MHz chips?

Robert

Art
- 16th May 2015, 01:34
Speed doesn’t address the problem Robert ( convenient floating point math),
but I should have tried out some faster pics years ago yes! :D

Richard, you’re probably right, and I didn’t think of that.
At least 16 bit rotation should take the same time, and in this instance the bytes don’t have to be bytes.
I don’t think C can create an alias of another variable type like PBP does (it might cost more time to access them)
but accessing an array out of bounds has worked on every platform I’ve tried, and probably for PBP too although not needed.




unsigned char bytearray[2];
long longarray[2];

Now bytearray[2],bytearray[3], etc. can access the bytes of longarray.

richard
- 16th May 2015, 02:49
you use a union
eg
union U32_
{
unsigned long l; // For accessing the whole 32-bits
unsigned char b[4]; // For accessing as individual bytes
};


char mybyte;

union u32_ my_array;
my_array.l= 0b00001111000011110000111100001111

mybyte=my_array.b[3];

Art
- 16th May 2015, 04:46
Thanks :) I’m sure that will be handy.