Main Site Documentation

C++ to C# Bit Wise Operations?


#1

I wonder if someone that is skilled in the art of C++ Bit Wise opps can verify and see where my errors are please?

My kills in C++ are very poor unfortunately.


 // void STM32F4_GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
private void GPIO_Init(GPIO GPIOx, GPIO_InitStructure GPIO_InitStruct)
 {
 // uint32_t pinpos = 0x00, pos = 0x00 , currentpin = 0x00;
uint pinpos = 0x00, pos = 0x00, currentpin = 0x00;


// -------------------------Configure the port pins---------------- 
 //-- GPIO Mode Configuration --
for (pinpos = 0x00; pinpos < 0x10; pinpos++)
{
 pos = ((uint)0x01) << (int)pinpos;
// Get the port pins position 
 // pos = ((uint32_t)0x01) << pinpos;
currentpin = (GPIO_InitStructure.GPIO_Pin) & pos;

if (currentpin == pos)
{
 // GPIOx->MODER  &= ~(GPIO_MODER_MODER0 << (pinpos * 2));
GPIOx.MODER_Register.Write(GPIOx.MODER &= ~(STM32F4xx.GPIO_MODER_MODER0 << (int)(pinpos * 2)));
// GPIOx->MODER |= (((uint32_t)GPIO_InitStruct->GPIO_Mode) << (pinpos * 2));
GPIOx.MODER_Register.Write(GPIOx.MODER  |= (((UInt32)GPIO_InitStructure.GPIOMode) << (int)(pinpos * 2)));

if ((GPIO_InitStructure.GPIOMode == GPIOMode.GPIO_Mode_OUT) || (GPIO_InitStructure.GPIOMode == GPIOMode.GPIO_Mode_AF))
 {
// Check Speed mode parameters 
//assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));

// Speed mode configuration 
// GPIOx->OSPEEDR &= ~(GPIO_OSPEEDER_OSPEEDR0 << (pinpos * 2));
GPIOx.OTYPER_Register.Write(GPIOx.OSPEEDR &= ~(STM32F4xx.GPIO_OSPEEDER_OSPEEDR0 << (int)(pinpos * 2)));
// GPIOx->OSPEEDR |= ((uint32_t)(GPIO_InitStruct->GPIO_Speed) << (pinpos * 2));
GPIOx.OTYPER_Register.Write(GPIOx.OSPEEDR |= ((UInt32)(GPIO_InitStructure.GPIO_Speed) << (int)(pinpos * 2)));

// Check Output mode parameters 
//assert_param(IS_GPIO_OTYPE(GPIO_InitStruct->GPIO_OType));

// Output mode configuration
// GPIOx->OTYPER  &= ~((GPIO_OTYPER_OT_0) << ((uint16_t)pinpos)) ;
GPIOx.OTYPER_Register.Write(GPIOx.OTYPER &= ~((STM32F4xx.GPIO_OTYPER_OT_0) << ((UInt16)pinpos)));
// GPIOx->OTYPER |= (uint16_t)(((uint16_t)GPIO_InitStruct->GPIO_OType) << ((uint16_t)pinpos));
GPIOx.OTYPER_Register.Write(GPIOx.OTYPER |= (UInt16)(((UInt16)GPIO_InitStructure.GPIO_OType) << ((UInt16)pinpos)));
}

// Pull-up Pull down resistor configuration
GPIOx.PUPDR_Register.Write(STM32F4xx.GPIO_PUPDR_PUPDR0 << ((UInt16)pinpos * 2));
// GPIOx->PUPDR |= (((uint32_t)GPIO_InitStruct->GPIO_PuPd) << (pinpos * 2));
GPIOx.PUPDR_Register.Write((uint)(GPIOx.PUPDR |= ((GPIO_InitStructure.GPIO_PuPd) << (int)(pinpos * 2))));
 }
 }
}

private void GPIO_PinAFConfig(GPIO GPIOx, UInt16 GPIO_PinSource, byte GPIO_AF)
 {
UInt32 temp = 0x00;
UInt32 temp_2 = 0x00;

// temp = ((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
temp = ((UInt32)(GPIO_AF) << (int)((UInt32)((UInt32)GPIO_PinSource & (UInt32)0x07) * 4));
 // GPIOx->AFR[GPIO_PinSource >> 0x03] &= ~((uint32_t)0xF << ((uint32_t)((uint32_t)GPIO_PinSource & (uint32_t)0x07) * 4)) ;
GPIOx.AFRH_Register.Write(GPIOx.AFRH &= ~((UInt32)0xF << (int)((UInt32)((UInt32)GPIO_PinSource & (UInt32)0x07) * 4)));
// temp_2 = GPIOx->AFR[GPIO_PinSource >> 0x03] | temp;
temp_2 = GPIOx.AFRH | temp;
// GPIOx->AFR[GPIO_PinSource >> 0x03] = temp_2;
GPIOx.AFRH_Register.Write(temp_2);
}

Code is from the STM32F4_GPIO_Functions.cpp doc on the codeshare website.

See: http://ghiopensource.codeplex.com/SourceControl/latest#DeviceCode/Targets/Native/STM32F4/DeviceCode/STM32F4_GPIO/STM32F4_GPIO_functions.cpp

Your help and guidance is much appreciated.


#2

Not sure what the title has to do with the content of your post (C# ?), and I also don’t know where you might think to have any errors.
But in general there is no difference between C++ and C# bitwise operations, as long as you work without pointers.


#3

Hi Reinhard,

one error I have been getting is: “Operator ‘<<’ cannot be applied to operands of type ‘uint’ and ‘uint’”

To resolve this I have had to cast the right hand operator to an ‘int’


((UInt32)(GPIO_AF) << ((UInt32)((UInt32)GPIO_PinSource8 & (UInt32)0x07) * 4))

Adding ‘(int)’ to:


((UInt32)(GPIO_AF) << (int)((UInt32)((UInt32)GPIO_PinSource8 & (UInt32)0x07) * 4))

I feel this is incorrect? Thus, the Bit Wise Operation may not be the same and 32 bit registers may over flow and cause incorrect values being returned.

However many functions do return the same value:


// Returns 18;
((UInt32)(GPIO_AF) << (int)((UInt32)((UInt32)GPIO_PinSource8 & (UInt32)0x07) * 4))

Where:


private static byte GPIO_AF = 0x12;
private static byte GPIO_PinSource8 = ((byte)0x08);


 #define GPIO_PinSource8            ((uint8_t)0x08)
 #define GPIO_AF 0x12

// Returns 18;
((uint32_t)(GPIO_AF) << ((uint32_t)((uint32_t)GPIO_PinSource8 & (uint32_t)0x07) * 4))

So yes many of the operations appear to be the same after some testing. However, to build that ‘better mouse trap’ a better way to manage the possibility of int overflow problems would be ideal.

All the best

Chris


#4

Thanks Andre!

Your link: http://stackoverflow.com/questions/15059524/bitwise-shift-in-uint does provide an answer!

Nice example. I have done some tests and interestingly results are good:

uint number = 0x418;
uint number1 = 0x8041;
uint number2 = 0x1804;

// number >> 4
// (number >> nbits) | (number << (16 - nbits))

int nbits = 0;

for (int i = 0; i < 20; i++)
{
Console.WriteLine("Result: {0:00} Result: {1:00} Where i = {2:00}.", (number1 >> nbits) | (number1 << (16 - nbits)), Convert.ToString(((number1 >> nbits) | (number1 << (16 - nbits))), 16), i);
nbits = i;
}

 Console.ReadLine();

Results:
Result: 2151776321 Result: 80418041 Where i = 00.
Result: 2151776321 Result: 80418041 Where i = 01.
Result: 1075888160 Result: 4020c020 Where i = 02.
Result: 537944080 Result: 20106010 Where i = 03.
Result: 268972040 Result: 10083008 Where i = 04.
Result: 134486020 Result: 8041804 Where i = 05.
Result: 67243010 Result: 4020c02 Where i = 06.
Result: 33621505 Result: 2010601 Where i = 07.
Result: 16810752 Result: 1008300 Where i = 08.
Result: 8405376 Result: 804180 Where i = 09.
Result: 4202688 Result: 4020c0 Where i = 10.
Result: 2101344 Result: 201060 Where i = 11.
Result: 1050672 Result: 100830 Where i = 12.
Result: 525336 Result: 80418 Where i = 13.
Result: 262668 Result: 4020c Where i = 14.
Result: 131334 Result: 20106 Where i = 15.
Result: 65667 Result: 10083 Where i = 16.
Result: 32833 Result: 8041 Where i = 17. <---- This is the result that the question was looking for…
Result: 2147483648 Result: 80000000 Where i = 18.
Result: 1073741824 Result: 40000000 Where i = 19.

This also shows that:



does indeed fix this overflow problem.

Thanks!!! +1