Code Snippets

Macros to get and set a bit field within a value

Ricky Bennett March 22, 2013 Coded in C
// Get a bit field from a value
#define GetField(Var, Mask, Shift) \
      (((Var) >> (Shift)) & (Mask))

// Set a bit field in a value
#define SetField(Var, Mask, Shift, Val) \
      (Var) = (((Var) & ~((Mask) << (Shift))) | (((Val) & (Mask)) << (Shift)))

Primitive exception processing using macros

Ricky Bennett March 22, 2013 Coded in C
#define Try \
      jmp_buf ExceptionBuffer; \
      int ExceptionStatus = setjmp (ExceptionBuffer); \
      if (ExceptionStatus == 0)

#define Catch(Value)    else if (ExceptionStatus == (int) (Value))

#define Finally         else

#define Throw(Value) \
      { \
         int Result = (int) (Value); \
         if (Result != 0) { \
            longjmp (ExceptionBuffer, Result); \
         } \
      }

An example using a function to read the OCR register on an SD card:

uint32_t SDCard_OCR (void) {
   SDCard_ConfigSSP ( );
   Try {

      // The card is asked to send its OCR.  The OCR is
      // placed in module variable mOCRValue by the
      // function.
      Throw (SDCard_SendCommand (CMD58_READ_OCR));
   }

   // Error processing.
   Catch (SD_TIMEOUT) {
      GUI_SendMessage (SDCARD_TIMEOUT);
   }
   Catch (SD_NO_CARD) {
      GUI_SendMessage (SDCARD_NOT_FOUND);
   }
   Finally {   // Unknown SD card error
      Throw (SD_NO_CARD);   // Rethrow the exception
   }

   // Executed even if an exception thrown:
   SDCard_DeconfigSSP ( );
   return mOCRValue;   // 0xFFFFFFFF if error
}

Graphics in source code

Ricky Bennett February 28, 20132 comments Coded in C
// This enum defines the value of each of the 256 possible combinations of
// underlines and Os in 8 bits.
enum
{
   ________,_______O,______O_,______OO,_____O__,_____O_O,_____OO_,_____OOO,
   ____O___,____O__O,____O_O_,____O_OO,____OO__,____OO_O,____OOO_,____OOOO,
   ___O____,___O___O,___O__O_,___O__OO,___O_O__,___O_O_O,___O_OO_,___O_OOO,
   ___OO___,___OO__O,___OO_O_,___OO_OO,___OOO__,___OOO_O,___OOOO_,___OOOOO,
   __O_____,__O____O,__O___O_,__O___OO,__O__O__,__O__O_O,__O__OO_,__O__OOO,
   __O_O___,__O_O__O,__O_O_O_,__O_O_OO,__O_OO__,__O_OO_O,__O_OOO_,__O_OOOO,
   __OO____,__OO___O,__OO__O_,__OO__OO,__OO_O__,__OO_O_O,__OO_OO_,__OO_OOO,
   __OOO___,__OOO__O,__OOO_O_,__OOO_OO,__OOOO__,__OOOO_O,__OOOOO_,__OOOOOO,
   _O______,_O_____O,_O____O_,_O____OO,_O___O__,_O___O_O,_O___OO_,_O___OOO,
   _O__O___,_O__O__O,_O__O_O_,_O__O_OO,_O__OO__,_O__OO_O,_O__OOO_,_O__OOOO,
   _O_O____,_O_O___O,_O_O__O_,_O_O__OO,_O_O_O__,_O_O_O_O,_O_O_OO_,_O_O_OOO,
   _O_OO___,_O_OO__O,_O_OO_O_,_O_OO_OO,_O_OOO__,_O_OOO_O,_O_OOOO_,_O_OOOOO,
   _OO_____,_OO____O,_OO___O_,_OO___OO,_OO__O__,_OO__O_O,_OO__OO_,_OO__OOO,
   _OO_O___,_OO_O__O,_OO_O_O_,_OO_O_OO,_OO_OO__,_OO_OO_O,_OO_OOO_,_OO_OOOO,
   _OOO____,_OOO___O,_OOO__O_,_OOO__OO,_OOO_O__,_OOO_O_O,_OOO_OO_,_OOO_OOO,
   _OOOO___,_OOOO__O,_OOOO_O_,_OOOO_OO,_OOOOO__,_OOOOO_O,_OOOOOO_,_OOOOOOO,
   O_______,O______O,O_____O_,O_____OO,O____O__,O____O_O,O____OO_,O____OOO,
   O___O___,O___O__O,O___O_O_,O___O_OO,O___OO__,O___OO_O,O___OOO_,O___OOOO,
   O__O____,O__O___O,O__O__O_,O__O__OO,O__O_O__,O__O_O_O,O__O_OO_,O__O_OOO,
   O__OO___,O__OO__O,O__OO_O_,O__OO_OO,O__OOO__,O__OOO_O,O__OOOO_,O__OOOOO,
   O_O_____,O_O____O,O_O___O_,O_O___OO,O_O__O__,O_O__O_O,O_O__OO_,O_O__OOO,
   O_O_O___,O_O_O__O,O_O_O_O_,O_O_O_OO,O_O_OO__,O_O_OO_O,O_O_OOO_,O_O_OOOO,
   O_OO____,O_OO___O,O_OO__O_,O_OO__OO,O_OO_O__,O_OO_O_O,O_OO_OO_,O_OO_OOO,
   O_OOO___,O_OOO__O,O_OOO_O_,O_OOO_OO,O_OOOO__,O_OOOO_O,O_OOOOO_,O_OOOOOO,
   OO______,OO_____O,OO____O_,OO____OO,OO___O__,OO___O_O,OO___OO_,OO___OOO,
   OO__O___,OO__O__O,OO__O_O_,OO__O_OO,OO__OO__,OO__OO_O,OO__OOO_,OO__OOOO,
   OO_O____,OO_O___O,OO_O__O_,OO_O__OO,OO_O_O__,OO_O_O_O,OO_O_OO_,OO_O_OOO,
   OO_OO___,OO_OO__O,OO_OO_O_,OO_OO_OO,OO_OOO__,OO_OOO_O,OO_OOOO_,OO_OOOOO,
   OOO_____,OOO____O,OOO___O_,OOO___OO,OOO__O__,OOO__O_O,OOO__OO_,OOO__OOO,
   OOO_O___,OOO_O__O,OOO_O_O_,OOO_O_OO,OOO_OO__,OOO_OO_O,OOO_OOO_,OOO_OOOO,
   OOOO____,OOOO___O,OOOO__O_,OOOO__OO,OOOO_O__,OOOO_O_O,OOOO_OO_,OOOO_OOO,
   OOOOO___,OOOOO__O,OOOOO_O_,OOOOO_OO,OOOOOO__,OOOOOO_O,OOOOOOO_,OOOOOOOO,
};

// These macros use the above enum to build the image in a source file.

#define G8(n0)                (n0)     //!< Build a byte image line

#define G16(n1, n0)           (((n1) << 8) | (n0))
                                       //!< Build a halfword image line

#define G32(n3, n2, n1, n0)                                                   \
      ((G16 ((n3), (n2)) << 16) | G16 ((n1), (n0)))
                                       //!< Build a word image line

#define G64(n7, n6, n5, n4, n3, n2, n1, n0)                                   \
      ((G32 ((n7), (n6), (n5), (n4)) << 32) | G32 ((n3), (n2), (n1), (n0)))
                                       //!< Build a long image line

=====

Example using the letter A in Arial Black 21 font:

Old code:

{
      19,                              // A
      0x00040000, 0x00078000, 0x0007F000, 0x0007FC00,
      0x0007FF80, 0x0003FFF0, 0x0000FFFC, 0x0000FFFE,
      0x0000F1FE, 0x0000F03E, 0x0000F1FE, 0x0000FFFE,
      0x0000FFFC, 0x0003FFF0, 0x0007FF80, 0x0007FC00,
      0x0007F000, 0x00078000, 0x00040000
};

New code:

{
      19,                              // A
      G32 (________,_____O__,________,________),
      G32 (________,_____OOO,O_______,________),
      G32 (________,_____OOO,OOOO____,________),
      G32 (________,_____OOO,OOOOOO__,________),
      G32 (________,_____OOO,OOOOOOOO,O_______),
      G32 (________,______OO,OOOOOOOO,OOOO____),
      G32 (________,________,OOOOOOOO,OOOOOO__),
      G32 (________,________,OOOOOOOO,OOOOOOO_),
      G32 (________,________,OOOO___O,OOOOOOO_),
      G32 (________,________,OOOO____,__OOOOO_),
      G32 (________,________,OOOO___O,OOOOOOO_),
      G32 (________,________,OOOOOOOO,OOOOOOO_),
      G32 (________,________,OOOOOOOO,OOOOOO__),
      G32 (________,______OO,OOOOOOOO,OOOO____),
      G32 (________,_____OOO,OOOOOOOO,O_______),
      G32 (________,_____OOO,OOOOOO__,________),
      G32 (________,_____OOO,OOOO____,________),
      G32 (________,_____OOO,O_______,________),
      G32 (________,_____O__,________,________),
};

Binary numbers

Ricky Bennett February 28, 2013 Coded in C
// The following macros build values in binary.  Nybbles are separated by
// commas for readability.  If a non-binary digit is used, a compiler error
// will result.  Here are some examples of the usage of the binary macros:
//
//    B4 (0110) = 0x06
//    B8 (0101,0101) = 0x55
//    B16 (1010,1010, 0101,0101) = 0xAA55
//    B32 (1000,0000, 1111,1111, 1010,1010, 0101,0101) = 0x80FFAA55
//
// For maximum readability, the bytes should be separated by spaces and there
// should be no spaces between nybbles, as shown above.  Note that an enum
// isn't used because MISRA-C generates errors otherwise.

#define b0000   0u
#define b0001   1u
#define b0010   2u
#define b0011   3u
#define b0100   4u
#define b0101   5u
#define b0110   6u
#define b0111   7u
#define b1000   8u
#define b1001   9u
#define b1010  10u
#define b1011  11u
#define b1100  12u
#define b1101  13u
#define b1110  14u
#define b1111  15u

#pragma diag_suppress = Pm120
#define B4(n0)                (b##n0)  //!< Build a nybble in binary
#pragma diag_default = Pm120

#define B8(n1, n0)            ((B4 (n1) << 4u) | B4 (n0))
                                       //!< Build a byte in binary

#define B16(n3, n2, n1, n0)                                                   \
      ((B4 (n3) << 12) | (B4 (n2) << 8) | (B4 (n1) << 4) | B4 (n0))
                                       //!< Build a halfword in binary

#define B32(n7, n6, n5, n4, n3, n2, n1, n0)                                   \
       ((B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
      | (B4 (n3) << 12) | (B4 (n2) <<  8) | (B4 (n1) <<  4) | B4 (n0))
                                       //!< Build a word in binary

#define B64(nF, nE, nD, nC, nB, nA, n9, n8, n7, n6, n5, n4, n3, n2, n1, n0)   \
       ((B4 (nF) << 60) | (B4 (nE) << 56) | (B4 (nD) << 52) | (B4 (nC) << 48) \
      | (B4 (nB) << 44) | (B4 (nA) << 40) | (B4 (n9) << 36) | (B4 (n8) << 32) \
      | (B4 (n7) << 28) | (B4 (n6) << 24) | (B4 (n5) << 20) | (B4 (n5) << 16) \
      | (B4 (n3) << 12) | (B4 (n2) <<  8) | (B4 (n1) <<  4) |  B4 (n0))
                                       //!< Build a long in binary