Wednesday, September 7, 2011

Stupid Programmer Tricks, C++

Ok,
I've been diving into C++ after not using it for a long time.  There are some pitfalls that have cost allot of time.
Rather than clutter things up with angry exclamation points to show frustration, I'll make the simple statements.


  1. Destructors must be declared virtual in the base class or the child class destructor will not get called.
  2. You can declare a variable in a base class and then declare it in the child class and no compiler error or warning gets generated.  But they are different variables and when you set, NULL, or delete one, the other is untouched, with very ugly side effects.
  3. You must always initialize variables or they will contain garbage.  In particular, you must set pointers to NULL
Now I bet there are compiler flags I could have set or some such, but they are not the default Visual Studio C++ settings. Hope I saved you some time.

TF

Saturday, August 20, 2011

Permaculture and Rocks - Mico-dams

So I was studying my yard for about an hour today.  This "study" consists of walking around while the sprinklers run and just looking.  The back of my yard is a very steep slope up to the yard behind us.  I'm in Utah so we are in an alpine desert.  The slope is eroding.

After a while I began asking my self, "why does that plant (weed?) grow there?"  I noticed that around the rocks that are a foot around lots of plants grow. but on the barren eroding slope nothing grows.  The dirt eroding down the hill get dammed up behind the rocks and forms a small flat spot where the plants grow.


The rocks also deflect the rain to the plants and keep the soil under the rock cooler and moist.  Our back patio has nice green grass between the flagstones for the same reason.

I have taken lots of the rocks that were along the bottom of the slope, and moved them up into the erosion gullies as little dams to hold back the dirt.  We will see how it looks next summer.

P.S. In the spirit of getting many synergistic things done at once, I also got some good weight lifting in without the cost of a Spa.

TF

Friday, July 29, 2011

On Not Watching TV

Sometimes some aspect of life can disappear and you don't even notice for a long while...

A while back we stopped paying out Comcast bill.  They eventually shut us off, and a few weeks later some guy showed up and retrieved the cable boxes when I wasn't home.

At some point after several weeks of no TV, I realized that the TV no longer worked!

We still have internet and NetFlix, still have the HDTV in the basement for NetFlix BlueRay, and all the XBoxen, Wiii, etc. so it's not like we are unplugged.  We watch TV shows, but when we want to, on our schedule.

So some thoughts are in order in regard to the great wasteland that is TV.
  • Wow, the house is quieter in the evenings. Before, there was always the TV in in the evenings and loud too.
  • Everyone is doing more interesting things, at a minimum on the computers instead where it is interactive activities.
  • The stress of TV is gone, let me explain: Most TV shows, if you get far away and listen to the voice tone instead of the actual words, are all people with tons of stress in their voices.  The 'reality' shows which Weird Al parodies so well, are all borderline psychotic people emoting about some tragedy.  The predominant emotions on TV are stress, fear, violence, fright, anxiety and such.
It is probably 'writing on the wall' that my TV could disappear and I didn't even notice for a few weeks.  The networks are doomed.

TF

Thursday, July 14, 2011

On Raw Salad

So after reading a raw foods book, where they suggest you eat only live food, and another book by Art DeVany about paleofitness, I have been eating more salads.

So I bought a organic salad mix of baby greens in a plastic box.  I didn't have any salad dressing, so I just ate from the box like the leaves were potato chips.

Wow, each type of leaf has a unique flavor.  When you drown a salad in dressing, you miss what the actual salad tastes like!

It sort of surprises your tongue when you put in a leaf, since you never know what a given leaf will taste like.

TF

Friday, July 8, 2011

NetLib C++ bug fix in Advanced 3D Game Programming with DirectX 10.0

Ok,
I'm using NetLib and got a packet to transmit and receive, but there was a crash.

In QueueIn.cpp in AddPacket the line
pPacket = *d_packetsUnordered.begin();
Throws on the first packet.
Just before that line you need...

if(d_packetsUnordered.size() > 0)
{


TF
 
 

Friday, June 10, 2011

Notes on I2C and SSI bus implementation

A quick note:

When you implement I2C and/or SSI you must implement timeouts and anit-lockup code.
Both busses are driven with statements like

while(some flag)  wait forever.

And you can get locked up if there is a single clock glitch.


void I2CResetLoopTimer(int i2cDeviceIdx)
{
  xI2CConfigHandle h = I2CDevices[i2cDeviceIdx];
  h->loopTimer = xTaskGetTickCount();
}


int I2CHasError(int i2cDeviceIdx)
{
  xI2CConfigHandle h = I2CDevices[i2cDeviceIdx];
  portTickType dt = xTaskGetTickCount() - h->loopTimer;
 
  return dt > 200 ||
    I2C_GetFlagStatus(h->i2cDevice, I2C_FLAG_TIMEOUT) ||
      I2C_GetFlagStatus(h->i2cDevice, I2C_FLAG_PECERR) ||
        I2C_GetFlagStatus(h->i2cDevice, I2C_FLAG_AF) ||
          I2C_GetFlagStatus(h->i2cDevice, I2C_FLAG_ARLO) ||
            I2C_GetFlagStatus(h->i2cDevice, I2C_FLAG_BERR);
}


int I2CHasErrorAndClear(int i2cDeviceIdx)
{
  if(I2CHasError(i2cDeviceIdx))
  {
    I2CClearError(i2cDeviceIdx);
    return true;
  }
  return false;
}

And an example loop.

int WhileBusy(int i2cDeviceIdx)
{
  xI2CConfigHandle h = I2CDevices[i2cDeviceIdx];
  
  I2CResetLoopTimer(i2cDeviceIdx);
  while (I2C_GetFlagStatus(h->i2cDevice, I2C_FLAG_BUSY))
  {
    if(I2CHasErrorAndClear(i2cDeviceIdx))
    {
      return false;
    }
    
    portYIELD();
  }
  return true;
}

TF

I2C Reset on ST Microsystems Processors

So,
You have a ST processor (e.g. STM32F103) and a I2C device.  If the device, bus, or processor gets a bit error in the I2C bus, it will lock up the bus.

After trying many solutions, this one works...



void I2C_ResetAndInit()
{
/* This shuts off power to the I2C circuit on the processor. */
I2C_DeInit(I2C1);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

/* SCL  pin enable */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

/* SDA pin enable  */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);

I2C_StructInit(&I2C1_InitDef);
// 400 khz.
I2C1_InitDef.I2C_ClockSpeed = 100000;
I2C_Init(I2C1, &I2C1_InitDef);

I2C_Cmd(I2C1, ENABLE);
}

And for the I2c Device out there on the bus...
Oh, we are using RTOS so that is the delayt and tick stuff.

portTickType Baro_LastErrorMessageTime = 0;
void BaroResetChip()
{
if(xTaskGetTickCount() - Baro_LastErrorMessageTime > 10000)
{
Baro_LastErrorMessageTime = xTaskGetTickCount();
mainMessagePrint(ROUTE_HALL, "Baro failed, reset.");
}

I2CClearError(I2C_DEVICE_BARO);
// Turn the baro power off and then back on.
// You DID put this in your design, right?
// Also, many I2C chips have a reset line that will do the same thing.
SetPwrBaro(0);
vTaskDelay(3000);
SetPwrBaro(1);

I2C_ResetAndInit();
}

In summary, the important pat is you must either reset or power cycle the I2C device, and you must use DeInit to power cycle the I2C internal device on the CPU.

TF