Why Microsoft .Net failed - Andrew Oliver

Why Microsoft .Net failed By Andrew Oliver Created 2013-08-29 03:00AM

http://www.infoworld.com/print/225817

Recently, I've been airing Java's dirty laundry [1]. Some folks took my position that Java was trailing .Net technically [2] to mean that I thought .Net was winning. Nothing of the kind -- in a number of important ways, .Net is a failure.

Think back a decade or so ago. As you may recall, .Net was supposed to be much more than just the next version of Windows DNA or COM+ or COM. It was supposed to destroy Java, extend the Windows platform, and secure the Microsoft monopoly for another decade or two.

...

Microsoft did many things right. It hired the smartest experts on language design, compilers, and virtual machines. But it also did some things terribly wrong.

Let's start with marketing. Microsoft overextended the .Net brand and stamped it on everything. At one point Windows Server was going to have .Net emblazoned on it, which led many people to wonder what the heck .Net was supposed to mean anyway.

At first, Microsoft made .Net an optional download. People were as excited to download the fat .Net VM full of delicious, possibly conflicting DLLs as they were to download a gigantic Java virtual machine.

Embrace, extend, flop

Like many Microsoft "innovations," .Net was a copy (embrace) and improvement (extend) of someone else's technology -- in this case, Java. Microsoft sought to extinguish Java by being a better Java; in a number of ways, it succeeded. C# cleaned up some Java mistakes, such as checked exceptions, the need to create an accessor, and mutator methods. The .Net VM had a cleaner bytecode setup.

Plus, .Net solved Microsoft's problems. At the time, Microsoft developers were dealing with more than one flavor of Windows and multiple versions, but .Net gave them a common way to code and less to worry about.

Unfortunately, .Net also cannibalized Microsoft's most successful corporate IT development environment, Visual Basic. Look at Indeed's Job Trends [6], Tiobe [7], and so on, and you'll notice that .Net's rise is all about Visual Basic's decline. There isn't a lot of correlation between .Net trends and Java's bumps and bends.

Visual Basic .Net didn't have much to recommend it. There wasn't enough documentation, so you had to learn C# anyhow. The API was the same between them, so why not just stick with C#? The corollary was that once you figured out C#, you also knew Java.

Sure, .Net stopped the bleeding for folks looking to develop Internet applications on Windows (away from tools that Microsoft controlled), but it didn't do what it was supposed to.

Instead of .Net propping up Windows, the greater Windows ecosystem propped up .Net. People coded to .Net because they were coding for SharePoint or BizTalk. If you delve deep into .Net jobs, you'll notice they tend to be legacy or related to SharePoint and friends.

Off to legacy land

Now it's too late for .Net. As we move from IaaS [8] to PaaS [9] and SaaS, folks are simply unlikely to care about operating systems. If you don't care about operating systems, why not code as if you don't care about operating systems and code for the cloud? We've seen recently that Azure isn't lighting the world on fire. Why would we expect that to change?

Even if you believe that most companies will continue to build their own data centers to care and feed, while ignoring the cloud, the desktop monopoly is also dying. Consumers are net information consumers. If you don't work in tech, publishing, or entertainment, then you probably take in more media than you produce. With the iPad, Android, and such, writing .Net isn't a viable business option. Miguel de Icaza [10] can create all the companies that begin with "x" that he likes, but people will continue to care less about Mono or be scared off by its patent ambiguity.

As users move from the desktop to the tablet and set top to view their pornography, cat pictures, and Netflix movies, the economics that caused folks to "target" Windows are abating. This results in a downward spiral for 'Softies hoping that writing to .Net is enough.

I could theorize about how Microsoft could extend .Net -- but why should it? .Net was about extending Windows. In a cloudy BYOD, tablet-oriented, Internet-standards-driven world, there may no longer be room for Microsoft, let alone .Net. The .Net initiative failed, and if you were part of it, I hope you hedged your bets by learning a few other tricks along the way.

This article, "Why Microsoft .Net failed [11]," was originally published at InfoWorld.com [12]. Keep up on the latest developments in application development [13], and read more of Andrew Oliver's Strategic Developer blog [14] at InfoWorld.com. For the latest business technology news, follow InfoWorld.com on Twitter [15].


.END

WHUT LPC11C14 Quad Key connection notes
























Quad key connection


.END

Echo 4 keys tested OK

// ***********************************************************************
// Program  - Test LPC1114
// Function - Test LPC1114
// Author   - TL Fong
// Build    - 2013.08.28.01
// Date     - 2013aug28hkt2239
// Hardware - LPC1114/102, LPC1114/301
// Software - GCC ARM 4.7, CoIDE 1.7.4,  CoLinkEx 1.1, Flash Magic v7.51
// ***********************************************************************

#include "test031.h"


// ***********************************************************************
// Functions
// ***********************************************************************

// ***********************************************************************
// Main Function
// ***********************************************************************

int main()
{
initSystem();
blinkLedAllDisplayDigitAll(); // blink all LEDs, display all digits

display1Digit(DIGIT_0); // display decimal digit 0

echo4Keys(); // echo key by LED

display1Digit(DIGIT_9); // display decimal digit 9

return 0;
}

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// test031.h
// ***********************************************************************

#include "blink031.h"
#include "blink032.h"
#include "display7SegLed031.h"
#include "key031.h"

void initSystem()
{
initializeAllOutputPins(WhutBoardLedPortPinArrayPointerArray, MAX_LED_NUMBER);

initializeAllOutputPins(WhutBoardSevenSegmentLedPortPinArrayPointerArray, \
MAX_7_SEG_LED_PIN_NUMBER);

initializeAllInputPins(WhutBoardKeyPortPinArrayPointerArray, MAX_KEY_NUMBER);
}

void blinkLedAllDisplayDigitAll()
{
blinkLedP18(ON_ONE_FIFTH_SECOND, OFF_ONE_FIFTH_SECOND, REPEAT_2_TIMES);

blinkLedP09(ON_ONE_FIFTH_SECOND, OFF_ONE_FIFTH_SECOND, REPEAT_2_TIMES);

blinkAllLeds(ON_ONE_FIFTH_SECOND, OFF_ONE_FIFTH_SECOND, REPEAT_2_TIMES);

displayAllDigits();
}

void echo4Keys()
{
echo1KeyBySingleLed(KEY_1, LED_1, REPEAT_1_TIME);
echo1KeyBySingleLed(KEY_2, LED_2, REPEAT_1_TIME);
echo1KeyBySingleLed(KEY_3, LED_3, REPEAT_1_TIME);
echo1KeyBySingleLed(KEY_4, LED_4, REPEAT_1_TIME);

// echo1KeyBy7SegmentLed(KEY_1, DIGIT_1, REPEAT_1_TIME);
// echo1KeyBy7SegmentLed(KEY_1, DIGIT_2, REPEAT_1_TIME);
// echo1KeyBy7SegmentLed(KEY_2, DIGIT_1, REPEAT_1_TIME);
// echo1KeyBy7SegmentLed(KEY_2, DIGIT_2, REPEAT_1_TIME);
}

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// * config031.h *
// ***********************************************************************

#include "lpc11xx_syscon.h"
#include "lpc11xx_gpio.h"
#include "lpc11xx_iocon.h"
#include "lpc11xx_uart.h"

#ifndef CONFIG_HEADER_SEEN
#define CONFIG_HEADER_SEEN

// ***********************************************************************
// * Logic voltage level, IO direction *
// ***********************************************************************

#define LOW 0
#define HIGH 1

#define LOW_LEVEL 0
#define HIGH_LEVEL 1

#define LOGIC_LOW_LEVEL 0
#define LOGIC_HIGH_LEVEL 1

typedef int logicLevelValue;

logicLevelValue LogicLevelLow = 0;
logicLevelValue LogicLevelHigh = 1;

// ***********************************************************************
// * GPIO Direction *
// ***********************************************************************

#define INPUT_DIRECTION 0
#define OUTPUT_DIRECTION 1

typedef int directionValue;

directionValue InputDirection = 0;
directionValue OutputDirection = 1;


// ***********************************************************************
// * Delay tenth seconds *
// ***********************************************************************

#define ONE_FIFTH_SECOND  2
#define ONE_HALF_SECOND   5
#define ONE_SECOND       10
#define TWO_SECONDS      20

#define ON_ONE_FIFTH_SECOND   2
#define OFF_ONE_FIFTH_SECOND  2
#define ON_ONE_HALF_SECOND    5
#define OFF_ONE_HALF_SECOND   5
#define ON_ONE_SECOND        10
#define OFF_ONE_SECOND       10

// ***********************************************************************
// * Repeat times *
// ***********************************************************************

#define REPEAT_1_TIME 1
#define REPEAT_2_TIMES 2
#define REPEAT_3_TIMES 3
#define REPEAT_4_TIMES 4
#define REPEAT_5_TIMES 5
#define REPEAT_6_TIMES 6
#define REPEAT_8_TIMES 8
#define REPEAT_10_TIMES 10
#define REPEAT_20_TIMES 20

// *** GPIO port number, pin number, port/pin number ***

#define PORT0 0
#define PORT1 1
#define PORT2 2
#define PORT3 3

#define PIN0 0
#define PIN1 1
#define PIN2 2
#define PIN3 3
#define PIN4 4
#define PIN5 5
#define PIN6 6
#define PIN7 7
#define PIN8 8
#define PIN9 9
#define PIN10 10
#define PIN11 11

typedef int portNumber;
portNumber Port0 = 0;
portNumber Port1 = 1;
portNumber Port2 = 2;
portNumber Port3 = 3;

typedef int pinNumber;
pinNumber Pin0  =  0;
pinNumber Pin1  =  1;
pinNumber Pin2  =  2;
pinNumber Pin3  =  3;
pinNumber Pin4  =  4;
pinNumber Pin5  =  5;
pinNumber Pin6  =  6;
pinNumber Pin7  =  7;
pinNumber Pin8  =  8;
pinNumber Pin9  =  9;
pinNumber Pin10 = 10;
pinNumber Pin11 = 11;

typedef const int portPinNumber;

portPinNumber Pio05  = 5;
portPinNumber Pio08  = 8;
portPinNumber Pio09  = 9;

portPinNumber Rpio11 = 11;
portPinNumber Rpio12 = 12;
portPinNumber Pio19  = 19;
portPinNumber Rpio18 = 18;
portPinNumber Pio110  = 110;

// *** system timer number, match register number ***

typedef const int timerNumber;
timerNumber Ct16b0 = 0;
timerNumber Ct16b1 = 1;
timerNumber Ct32b0 = 2;
timerNumber Ct32b1 = 3;

typedef const int matchRegisterNumber;
matchRegisterNumber MatchRegister0 = 0;
matchRegisterNumber MatchRegister1 = 1;
matchRegisterNumber MatchRegister2 = 2;

typedef const int deviceNumber;

#define LED1 1
#define LED2 2
#define LED3 3
#define LED4 4
#define LED5 5

#define LED_1 1
#define LED_2 2
#define LED_3 3
#define LED_4 4
#define LED_5 5

#define DIGIT_0 0
#define DIGIT_1 1
#define DIGIT_2 2
#define DIGIT_3 3
#define DIGIT_4 4
#define DIGIT_5 5
#define DIGIT_6 6
#define DIGIT_7 7
#define DIGIT_8 8
#define DIGIT_9 9

#define KEY_1 1
#define KEY_2 2
#define KEY_3 3
#define KEY_4 4

#define MAX_DEVICE_NUMBER 2
#define MAX_LED_NUMBER    5
#define MAX_KEY_NUMBER    2
#define MAX_PWM_NUMBER    2

// *** Port pin array typedef and declaration ***

// ***********************************************************************
// typedef portPinArray[]
// Description - this array denotes a GPIO port pin.  It has two elements,
//   portNumber and pinNumber
// **********************************************************************

#define PORT_INDEX 0
#define PIN_INDEX 1

typedef int portPinArray[2];

// ***********************************************************************
// WHUT LP!1114 Evaluation Board configuration
// ***********************************************************************

const int MaxBoardDeviceNumber =  5;
const int MaxBoardLedNumber = 5;
const int MaxBoardKeyNumber = 3;
const int MaxBoardPwmNumber = 5;

portPinArray WhutBoardLedPortPinArray1 = {PORT1, PIN8};  // LED D1
portPinArray WhutBoardLedPortPinArray2 = {PORT1, PIN9};  // LED D2
portPinArray WhutBoardLedPortPinArray3 = {PORT1, PIN10}; // LED D3
portPinArray WhutBoardLedPortPinArray4 = {PORT1, PIN11}; // LED D4
portPinArray WhutBoardLedPortPinArray5 = {PORT0, PIN9};  // JTAG pin13

#define SCLK_INDEX 0
#define DIN_INDEX 1
#define LATCH_INDEX 2

// *** Seven segment LED data and control signals ***
portPinArray WhutBoardSevenSegmentLedPortPinArraySclk = {PORT2, PIN1}; // Serial Clock
portPinArray WhutBoardSevenSegmentLedPortPinArrayDin = {PORT2, PIN3}; // Data in
portPinArray WhutBoardSevenSegmentLedPortPinArrayLatch = {PORT2, PIN0}; // Latch

portPinArray WhutBoardKeyPortPinArray1 = {PORT2, PIN7};  // LCD D4 <<<<< 2013aug28
portPinArray WhutBoardKeyPortPinArray2 = {PORT2, PIN8};  // LCD D5 <<<<< 2013aug28
portPinArray WhutBoardKeyPortPinArray3 = {PORT2, PIN9};  // LCD D6 <<<<< 2013aug28
portPinArray WhutBoardKeyPortPinArray4 = {PORT2, PIN10}; // LCD D7 <<<<< 2013aug28

// ***********************************************************************
// typedef portPinArrayPointerArray
// Description - Array pointers to pin array
// **********************************************************************

// *** Led configuration ***

typedef portPinArray *portPinArrayPointerArray[MAX_DEVICE_NUMBER];

#define WHUT_MAX_LED_PIN_NUMBER 5

portPinArrayPointerArray WhutBoardLedPortPinArrayPointerArray[WHUT_MAX_LED_PIN_NUMBER] = \
  {&WhutBoardLedPortPinArray1, &WhutBoardLedPortPinArray2, \
  &WhutBoardLedPortPinArray3, &WhutBoardLedPortPinArray4, \
  &WhutBoardLedPortPinArray5};

// *** 7 Segment LED configuration ***

#define MAX_7_SEG_LED_PIN_NUMBER 3

portPinArrayPointerArray WhutBoardSevenSegmentLedPortPinArrayPointerArray[MAX_7_SEG_LED_PIN_NUMBER] = \
  {&WhutBoardSevenSegmentLedPortPinArraySclk, &WhutBoardSevenSegmentLedPortPinArrayDin, \
       &WhutBoardSevenSegmentLedPortPinArrayLatch};

// *** Key configuration ***
#define MAX_KEY_PIN_NUMBER 4

portPinArrayPointerArray WhutBoardKeyPortPinArrayPointerArray[MAX_KEY_PIN_NUMBER] = \
 {&WhutBoardKeyPortPinArray1, &WhutBoardKeyPortPinArray2, \
 &WhutBoardKeyPortPinArray3, &WhutBoardKeyPortPinArray4};

// ***********************************************************************
// typedef mcuBoardStruct (To test later)
// Description - MCU Board struct with LEDs, Keys, and PWMs
// **********************************************************************

typedef struct
 {
 portPinArrayPointerArray *LedPortPinArrayPointerArray;
 portPinArrayPointerArray *KeyPortPinArrayPointerArray;
 portPinArrayPointerArray *PwmPortPinArrayPointerArray;
 } mcuBoardStruct;

// *** WHUT LPC1114 Evaluation Board Configuration ***

mcuBoardStruct *WHUT_LPC1114_EvaluationBoardStructPointer() // To be tested
 {
 mcuBoardStruct *WHUT_LPC1114_EValuationBoardStructPointer;

  // WHUT_LPC1114_EvaluationBoardStructPointer-> LedPortPinArrayPointerArray = \
  // WhutBoardLedPortPinArrayPointerArray;

  // WHUT_LPC1114_EvaluationBoardStructPointer-> SevenSegmentLedPortPinArrayPointerArray = \
  // WhutBoardSevenSegmentLedPortPinArrayPointerArray;

   // WHUT_LPC1114_EvaluationBoardStructPointer-> KeyPortPinArrayPointerArray = \
  // WhutBoardKeyPortPinArrayPointerArray;

  return WHUT_LPC1114_EValuationBoardStructPointer;
 }

// * typedefs of logic level and IO direction *

// ***********************************************************************
// typedef GPIO_TypeDef *gpioStructPointerArray[4];
// Description - CMSIS declares 4 struct pointers LPC_GPIO0, LPC_GPIO1,
// LPC_GPIO2, LPC_GPIO3 for the 4 structs each of which controls
// one port of up to 11 pins.
// ***********************************************************************

typedef GPIO_TypeDef *gpioStructPointerArray[4];
gpioStructPointerArray CmsisGpioStructPointerArray = {LPC_GPIO0, LPC_GPIO1, LPC_GPIO2, LPC_GPIO3};

#endif /* CONFIG_HEADER_SEEN */

// ***********************************************************************
// * End *
// ***********************************************************************


// ***********************************************************************
// display7SegLed031.h
// ***********************************************************************

#include "config031.h"
#include "delay031.h"
#include "gpio032.h"

void sendGoingPositivePulse(portPinArray *portPinArrayPointer)
{
setGpioDataPinHigh01(portPinArrayPointer);
setGpioDataPinLow01(portPinArrayPointer);
}

void loadSevenSegmentDataBits(portPinArray *portPinArrayPointerData, \
portPinArray *portPinArrayPointerClock, int alphaNumbericCharacter)
{
int segmentNumber;
int segmentBit;
int segmentByte, segmentByte1;

int Segment0 = 0b11111100;
int Segment1 = 0b01100000;
int Segment2 = 0b11011010;
int Segment3 = 0b11110010;
int Segment4 = 0b01100110;
int Segment5 = 0b10110110;
int Segment6 = 0b10111110;
int Segment7 = 0b11100000;
int Segment8 = 0b11111110;
int Segment9 = 0b11110110;

int SegmentArray[] = {Segment0, Segment1, Segment2, Segment3, Segment4, \
             Segment5, Segment6, Segment7, Segment8, Segment9};

segmentByte = SegmentArray[alphaNumbericCharacter];

    for (segmentNumber = 0; segmentNumber < 8; segmentNumber++)
    {
    segmentByte1 = segmentByte | (1 << segmentNumber);
    if (segmentByte1 == segmentByte)
      setGpioDataPinHigh01(portPinArrayPointerData);
    else
    setGpioDataPinLow01(portPinArrayPointerData);

        sendGoingPositivePulse(portPinArrayPointerClock);
    }
}

void display1Digit01(portPinArrayPointerArray sevenSegmentPortPinArrayPointerArray, \
int digitNumber)
{
portPinArray *portPinArrayPointerClock;
portPinArray *portPinArrayPointerData;
portPinArray *portPinArrayPointerLatch;

portPinArrayPointerClock = sevenSegmentPortPinArrayPointerArray[SCLK_INDEX];
portPinArrayPointerData  = sevenSegmentPortPinArrayPointerArray[DIN_INDEX];
portPinArrayPointerLatch = sevenSegmentPortPinArrayPointerArray[LATCH_INDEX];

setGpioDataPinLow01(portPinArrayPointerLatch);

setGpioDataPinLow01(portPinArrayPointerClock);

loadSevenSegmentDataBits(portPinArrayPointerData, portPinArrayPointerClock, digitNumber);

setGpioDataPinHigh01(portPinArrayPointerLatch);
}

void display1Digit(int digitNumber)
{
display1Digit01(WhutBoardSevenSegmentLedPortPinArrayPointerArray, digitNumber);
}

// ***********************************************************************
// Function - Display all digits
// ***********************************************************************

void displayAllDigits()
{
int digitNumber;

// initializeAllOutputPins(WhutBoardSevenSegmentLedPortPinArrayPointerArray, \
// MAX_7_SEG_LED_PIN_NUMBER);

    for (digitNumber = 0; digitNumber < 10; digitNumber++)
    {
    display1Digit(digitNumber);
    delayTime(ONE_HALF_SECOND);
    }
}

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// gpio031.h
// ***********************************************************************

#ifndef GPIO031_HEADER_SEEN
#define GPIO031_HEADER_SEEN

#include "lpc11xx_syscon.h"
#include "lpc11xx_gpio.h"
#include "lpc11xx_iocon.h"
#include "lpc11xx_uart.h"

#include "config031.h"
#include "delay031.h"

// ***********************************************************************
// *** PIO1_8, PIO0_9 functions ***
// ***********************************************************************

// *** PIO1_8 ***

void setPio18Direction(int direction)
{
 /* Set pin to GPIO */
 IOCON_SetPinFunc(IOCON_PIO1_8, PIO1_8_FUN_PIO);

  /* Set pin direction */
 if (direction == OUTPUT_DIRECTION)
  GPIO_SetDir(PORT1, GPIO_Pin_8, 1);
 else
  GPIO_SetDir(PORT1, GPIO_Pin_8, 0);
}

void setPio18OutputHigh()
{
 GPIO_SetBits(PORT1, GPIO_Pin_8);
}

void setPio18OutputLow()
{
 GPIO_ResetBits(PORT1, GPIO_Pin_8);
}

void setPio18Output(int logicLevel)
{
 if (logicLevel == HIGH_LEVEL)
  GPIO_SetBits(PORT1, GPIO_Pin_8);
 else
  GPIO_ResetBits(PORT1, GPIO_Pin_8);
}

// *** PIO0_9 ***

void setPio09Direction(int direction)
{
 /* Set pin to GPIO */
 IOCON_SetPinFunc(IOCON_PIO0_9, PIO0_9_FUN_PIO);

  /* Set pin direction */
 if (direction == OUTPUT_DIRECTION)
  GPIO_SetDir(PORT0, GPIO_Pin_9, 1);
 else
  GPIO_SetDir(PORT0, GPIO_Pin_9, 0);
}

void setPio09OutputHigh()
{
 GPIO_SetBits(PORT0, GPIO_Pin_9);
}

void setPio09OutputLow()
{
 GPIO_ResetBits(PORT0, GPIO_Pin_9);
}

// ***********************************************************************
// *** blink P18, P09 LEDs ***
// ***********************************************************************

void setPio09Output(int logicLevel)
{
 if (logicLevel == HIGH_LEVEL)
  GPIO_SetBits(PORT0, GPIO_Pin_9);
 else
  GPIO_ResetBits(PORT0, GPIO_Pin_9);
}

#endif /* GPIO031_HEADER_SEEN */

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// gpio032.h
// ***********************************************************************

// ***********************************************************************
// Program  - Fong Seven Segment LED
// Function - Display 7 segment LED
// Author   - TL Fong
// Build    - 2013.08.23.02
// Date     - 2013aug23hkt1750
// Hardware - LPC1114/301, LPC1114/102,
// Software - GCC ARM 4.7, CoIDE 1.7.4,  CoLinkEx 1.1, Flash Magic v7.51
// ***********************************************************************

#ifndef GPIO032_HEADER_SEEN
#define GPIO032_HEADER_SEEN

#include "lpc11xx_syscon.h"
#include "lpc11xx_gpio.h"
#include "lpc11xx_iocon.h"
#include "lpc11xx_uart.h"

#include "config031.h"
#include "delay031.h"

// ***********************************************************************
// Function List
// ***********************************************************************

// GPIO_TypeDef *getGpioStructPointer(int portNumber)
// gpioPortStructPinStruct *getGpioPortStructPinStructPointer \
(portNumber portNumber, pinNumber pinNumber)

// void setGpioDataPinInput(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
// void setGpioDataPinOutput(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)

// void setGpioDataPinLow(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
// void setGpioDataPinHigh(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)

// void setGpioPinDirection(GPIO_TypeDef *gpio_struct_ptr, int pinNumber, directionValue directionValue)

// void setGpioDataPin(GPIO_TypeDef *gpio_struct_ptr, int pinNumber, logicLevelValue logicLevelValue)

// logicLevelValue getGpioDataPinValue(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)

// portNumber getPortNumber(portPinArray portPinArray)
// portNumber getPortNumber01(portPinArrayPointerArray portPinArrayPointerArray, deviceNumber deviceNumber)

// pinNumber getPinNumber(portPinArray portPinArray)
// pinNumber getPinNumber01(portPinArrayPointerArray portPinArrayPointerArray, deviceNumber deviceNumber)

// void initializeOneOutputPin(portPinArrayPointerArray outputPortPinArrayPointerArray, deviceNumber deviceNumber)
// void initializeAllOutputPins(portPinArrayPointerArray outputPortPinArrayPointerArray, int maxPinNumber)


// ***********************************************************************
// GPIO functions
// ***********************************************************************

// ***********************************************************************
// Name   - getGpioStructPointer()
// Input  - port number
// Output - pointer to the struct of the port
// ***********************************************************************

GPIO_TypeDef *getGpioStructPointer(int portNumber)
{
 GPIO_TypeDef *gpioStructPointer;
 gpioStructPointer =  CmsisGpioStructPointerArray[portNumber];
 return gpioStructPointer;
}

// ***********************************************************************
// typedef gpioPortStructPinStruct;
// Description - this struct has 2 members: *GpioStructPointer and pin
//   pin number. This struct is not yet being used.
// ***********************************************************************

typedef struct
{
 GPIO_TypeDef *GpioStructPointer;
 int PinNumber;
} gpioPortStructPinStruct;

// ***********************************************************************
// Name   - getGpioPortStructPinStructPointer() // To be tested
// Input  - port number, pin number
// Output - pointer to gpioPortStructPinStruct
// ***********************************************************************

gpioPortStructPinStruct *getGpioPortStructPinStructPointer(portNumber portNumber, pinNumber pinNumber)
  {
 gpioPortStructPinStruct *gpioPortStructPinStruct;
 gpioPortStructPinStruct->GpioStructPointer = getGpioStructPointer(portNumber);
 gpioPortStructPinStruct->PinNumber = pinNumber;
 return gpioPortStructPinStruct;
  }

// ***********************************************************************
// GPIO functions
// ***********************************************************************

// ***********************************************************************
// Name   - setGpioDataPinInput()
// Input  - gpio_struct_ptr, pin number
// Output - none
// ***********************************************************************

void setGpioDataPinInput(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
{
 gpio_struct_ptr->DIR  &= ~(1 << pinNumber);
}

// ***********************************************************************
// Name   - setGpioDataPinOutput
// Input  - port control structure, pin number
// Output - set pin as output
// ***********************************************************************

void setGpioDataPinOutput(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
{
 gpio_struct_ptr->DIR |= (1 << pinNumber);
}

// ***********************************************************************
// Name   - setGpioDataPinLow
// Input  - port control structure, pin number
// Output - none
// ***********************************************************************

void setGpioDataPinLow(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
{
 gpio_struct_ptr->DATA &= ~(1 << pinNumber);
}

// ***********************************************************************
// Name   - setGpioDataPinHigh
// Input  - port control structure, pin number
// Output - set pin as output
// ***********************************************************************

void setGpioDataPinHigh(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
{
 gpio_struct_ptr->DATA |= (1 << pinNumber);
}

// ***********************************************************************
// Name   - setGpioDataPinDirection
// Input  - port control structure, pin number, direction value
// Output - set pin as input or output
// ***********************************************************************

void setGpioPinDirection(GPIO_TypeDef *gpio_struct_ptr, int pinNumber, directionValue directionValue)
{
 if (directionValue == INPUT_DIRECTION)
  setGpioDataPinInput(gpio_struct_ptr, pinNumber);
 else
  setGpioDataPinOutput(gpio_struct_ptr, pinNumber);
}

// ***********************************************************************
// Name   - setGpioDataRegister
// Input  - port control structure, pin number, data value
// Output - none
// ***********************************************************************

void setGpioDataPin(GPIO_TypeDef *gpio_struct_ptr, int pinNumber, logicLevelValue logicLevelValue)
{
 if (logicLevelValue == LOGIC_LOW_LEVEL)
  setGpioDataPinLow(gpio_struct_ptr, pinNumber);
 else
  setGpioDataPinHigh(gpio_struct_ptr, pinNumber);
}

// ***********************************************************************
// Function - getGpioDataPinValue
// Input    - GPIO structure pointer, pin number
// Output   - Gpio data pin value
// ***********************************************************************

logicLevelValue getGpioDataPinValue01(GPIO_TypeDef *gpio_struct_ptr, int pinNumber)
{
 logicLevelValue logicLevelValue;

  int GpioDataPinMask = (1 << pinNumber);

  if ((gpio_struct_ptr->DATA  &= GpioDataPinMask) == GpioDataPinMask)
  logicLevelValue = HIGH;
 else
  logicLevelValue = LOW;

  return logicLevelValue;
}

logicLevelValue getGpioDataPinValue(portPinArrayPointerArray inputPortPinArrayPointerArray, int pinNumber)
{
int portNumber;
GPIO_TypeDef *gpioStructPointer;
logicLevelValue logicLevelValue;

portNumber = getPortNumber01(inputPortPinArrayPointerArray, pinNumber);
gpioStructPointer = getGpioStructPointer(portNumber);
pinNumber = getPinNumber01(inputPortPinArrayPointerArray, pinNumber);

logicLevelValue = getGpioDataPinValue01(gpioStructPointer, pinNumber);

return logicLevelValue;
}

// ***********************************************************************
// Name   - get port number of portPinArray
// Input  - port pin array
// Output - portNumber
// ***********************************************************************

portNumber getPortNumber(portPinArray portPinArray)
{
 int portNumber;
 portNumber = portPinArray[PORT_INDEX];
 return portNumber;
}

// ***********************************************************************
// Name   - get port number from portPinArrayPointerArray
// Input  - portPinPointerArray, deviceNumber
// Output - portNumber
// ***********************************************************************

portNumber getPortNumber01(portPinArrayPointerArray portPinArrayPointerArray, deviceNumber deviceNumber)
{
 int portNumber;
 portNumber = getPortNumber(*portPinArrayPointerArray[deviceNumber - 1]);
 return portNumber;
}

// ***********************************************************************
// Name   - get pin number of portPinArray
// Input  - port pin array
// Output - pinNumber
// ***********************************************************************

pinNumber getPinNumber(portPinArray portPinArray)
{
 int pinNumber;
 pinNumber = portPinArray[PIN_INDEX];
 return pinNumber;
}

// ***********************************************************************
// Name   - get pin number from portPinArrayPointerArray and index
// Input  - portPinPointerArray, index
// Output - pinNumber
// ***********************************************************************

pinNumber getPinNumber01(portPinArrayPointerArray portPinArrayPointerArray, deviceNumber deviceNumber)
{
 int pinNumber;
 pinNumber = getPinNumber(*portPinArrayPointerArray[deviceNumber - 1]);
 return pinNumber;
}

// ***********************************************************************
// Name   - initialize one output pin
// Input  - outputPortPinPointerArray, index
// Output - none
// ***********************************************************************

void initializeOneOutputPin(portPinArrayPointerArray outputPortPinArrayPointerArray, deviceNumber deviceNumber)
{
int portNumber;
int pinNumber;
GPIO_TypeDef *gpioStructPointer;

portNumber = getPortNumber01(outputPortPinArrayPointerArray, deviceNumber);
gpioStructPointer = getGpioStructPointer(portNumber);
pinNumber = getPinNumber01(outputPortPinArrayPointerArray, deviceNumber);

setGpioDataPinOutput(gpioStructPointer, pinNumber);
setGpioDataPinLow (gpioStructPointer, pinNumber);
  }

// ***********************************************************************
// Function - initialize all output port pins
// Input    - outputPortPinArrayPointerArray
// Output   - none
// ***********************************************************************

void initializeAllOutputPins(portPinArrayPointerArray outputPortPinArrayPointerArray, int maxPinNumber)
{
  int pinNumber;

  for (pinNumber = 1; pinNumber < (maxPinNumber + 1); pinNumber++)
  {
   initializeOneOutputPin(outputPortPinArrayPointerArray, pinNumber);
  }
}

// ***********************************************************************
// Name   - initialize one input pin
// Input  - outputPortPinPointerArray, index
// Output - none
// ***********************************************************************

void initializeOneInputPin(portPinArrayPointerArray outputPortPinArrayPointerArray, \
deviceNumber deviceNumber)
{
int portNumber;
int pinNumber;
GPIO_TypeDef *gpioStructPointer;

portNumber = getPortNumber01(outputPortPinArrayPointerArray, deviceNumber);
gpioStructPointer = getGpioStructPointer(portNumber);
pinNumber = getPinNumber01(outputPortPinArrayPointerArray, deviceNumber);

setGpioDataPinInput(gpioStructPointer, pinNumber);
  }

// ***********************************************************************
// Function - initialize all input port pins
// Input    - outputPortPinArrayPointerArray
// Output   - none
// ***********************************************************************

void initializeAllInputPins(portPinArrayPointerArray inputPortPinArrayPointerArray, int maxPinNumber)
{
  int pinNumber;

  for (pinNumber = 1; pinNumber < (maxPinNumber + 1); pinNumber++)
  {
   initializeOneInputPin(inputPortPinArrayPointerArray, pinNumber);
  }
}

#endif /* GPIO032_HEADER_SEEN */

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// key031.h
// ***********************************************************************

#include "config031.h"
#include "delay031.h"
#include "gpio032.h"

// ***********************************************************************
// Key functions
// ***********************************************************************

logicLevelValue getKeyStatus();
void echo1Key01();
void echo1Key();
void testEchoThreeKeys();

// ***********************************************************************
// Function - getKeyStatus
// Input    - keyPortPinArrayPointerArray, keyNumber
// Output   - port pin data bit
// ***********************************************************************

logicLevelValue getKeyStatus(portPinArrayPointerArray keyPortPinArrayPointerArray, \
deviceNumber keyNumber)
{
logicLevelValue keyStatus;
int portNumber;
int pinNumber;
GPIO_TypeDef *gpio_struct_ptr;

keyStatus = getGpioDataPinValue(keyPortPinArrayPointerArray, keyNumber);

return keyStatus;
}

// ***********************************************************************
// Function - echo key by LED
// Input    - keyPinPortArrayPointerArray, keyNumber, ledPinPortArrayPointerArray, ledNumber
// Output   - none
// ***********************************************************************

// *** Echo key by single LED ***

void echo1KeyBySingleLed01(portPinArrayPointerArray keyPortPinArrayPointerArray, \
deviceNumber keyNumber, \
portPinArrayPointerArray ledPortPinArrayPointerArray, \
deviceNumber ledNumber, int echoCount)
{
int count;
logicLevelValue keyStatus;

for (count = 0; count < echoCount; count++)
{
delayTime(ONE_SECOND);

keyStatus = HIGH;
while (keyStatus == HIGH)
{
keyStatus = getKeyStatus(keyPortPinArrayPointerArray, keyNumber);

if (keyStatus == LOW)
{
blink1Led(ledNumber);
delayTime(TWO_SECONDS);
keyStatus = HIGH;
break;
}
}
}
}

void echo1KeyBySingleLed(deviceNumber keyNumber, int ledNumber, int repeatCount)
{
echo1KeyBySingleLed01(*WhutBoardKeyPortPinArrayPointerArray, keyNumber, \
*WhutBoardLedPortPinArrayPointerArray, ledNumber, \
repeatCount);
}


// *** Echo key by 7 segment LED ***

void echo1KeyBy7SegmentLed01(portPinArrayPointerArray keyPortPinArrayPointerArray, \
deviceNumber keyNumber, \
portPinArrayPointerArray sevenSegmentledPortPinArrayPointerArray, \
int digitNumber, int echoCount)
{
int count;
logicLevelValue keyStatus;

for (count = 0; count < echoCount; count++)
{
delayTime(ONE_SECOND);

keyStatus = HIGH;
while (keyStatus == HIGH)
{
keyStatus = getKeyStatus(keyPortPinArrayPointerArray, keyNumber);

if (keyStatus == LOW)
{
// blink1Led(ledNumber);
display1Digit(digitNumber);
delayTime(TWO_SECONDS);
keyStatus = HIGH;
break;
}
}
}
}

void echo1KeyBy7SegmentLed(deviceNumber keyNumber, int digitNumber, int repeatCount)
{
echo1KeyBy7SegmentLed01(*WhutBoardKeyPortPinArrayPointerArray, keyNumber, \
*WhutBoardSevenSegmentLedPortPinArrayPointerArray, digitNumber, \
repeatCount);
}


// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// blink031.h
// ***********************************************************************

#include "config031.h"
#include "delay031.h"
#include "gpio031.h"

void blinkLedP18(int onTime, int offTime, int repeatCount)
{
 // systemInitialization();
 setPio18Direction(OUTPUT_DIRECTION);

  int i;
 for (i = 0; i < repeatCount; i++)
 {
  setPio18Output(HIGH_LEVEL);
  delayTime(onTime);

   setPio18Output(LOW_LEVEL);
  delayTime(offTime);
 }
}

void blinkLedP09(int onTime, int offTime, int repeatCount)
{
 // systemInitialization();
 setPio09Direction(OUTPUT_DIRECTION);

  int i;
 for (i = 0; i < repeatCount; i++)
 {
  setPio09Output(HIGH_LEVEL);
  delayTime(onTime);

   setPio09Output(LOW_LEVEL);
  delayTime(offTime);
 }
}

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// blink032.h
// ***********************************************************************

#include "config031.h"
#include "delay031.h"
#include "gpio032.h"

// ***********************************************************************
// Blink LED functions
// ***********************************************************************

void setGpioDataPinHigh01(portPinArray *portPinArrayPointer)
{
pinNumber pinNumber;
portNumber portNumber;
GPIO_TypeDef *gpioStructPointer;

pinNumber = getPinNumber(portPinArrayPointer);
portNumber = getPortNumber(portPinArrayPointer);
gpioStructPointer = getGpioStructPointer(portNumber);
setGpioDataPinHigh(gpioStructPointer, pinNumber);
}

void setGpioDataPinLow01(portPinArray *portPinArrayPointer)
{
pinNumber pinNumber;
portNumber portNumber;
GPIO_TypeDef *gpioStructPointer;

pinNumber = getPinNumber(portPinArrayPointer);
portNumber = getPortNumber(portPinArrayPointer);
gpioStructPointer = getGpioStructPointer(portNumber);
setGpioDataPinLow(gpioStructPointer, pinNumber);
}

// ***********************************************************************
// Function - Blink 1 LED
// Input    - PortPinArrayPointerArray, device number, on time, off time,
//            blink repetition times
// Output   - none
// ***********************************************************************

void blink1Led01(portPinArrayPointerArray portPinArrayPointerArray, \
  deviceNumber ledNumber, int onTime, int offTime, int blinkCount)
{
int count = 0;
portPinArray *portPinArrayPointer;

portPinArrayPointer = portPinArrayPointerArray[ledNumber - 1];

   for (count = 0; count < blinkCount; count++)
   {
  setGpioDataPinHigh01(portPinArrayPointer);
  delayTenthSecond(onTime);
  setGpioDataPinLow01(portPinArrayPointer);
  delayTenthSecond(offTime);
   }
}

void blink1Led(int ledNumber)
{
blink1Led01(WhutBoardLedPortPinArrayPointerArray, ledNumber, \
ON_ONE_FIFTH_SECOND, OFF_ONE_FIFTH_SECOND, REPEAT_2_TIMES );
}

// ***********************************************************************
// Function - Blink all LEDs
// Input    - PortPinArrayPointerArray, device number, on time, off time,
//            blink repetition times
// Output   - none
// ***********************************************************************

void blinkAllLeds(int onTime, int offTime, int repeatCount)
{
int ledNumber;

// initializeAllOutputPins(WhutBoardLedPortPinArrayPointerArray, MAX_LED_NUMBER);

    for (ledNumber = 1; ledNumber < (MAX_LED_NUMBER + 1); ledNumber++ )
    {
    blink1Led01(WhutBoardLedPortPinArrayPointerArray, ledNumber, \
    onTime, offTime, repeatCount);
    }
}

// ***********************************************************************
// End
// ***********************************************************************




// ***********************************************************************
// display7SegLed031.h
// ***********************************************************************

#include "config031.h"
#include "delay031.h"
#include "gpio032.h"

void sendGoingPositivePulse(portPinArray *portPinArrayPointer)
{
setGpioDataPinHigh01(portPinArrayPointer);
setGpioDataPinLow01(portPinArrayPointer);
}

void loadSevenSegmentDataBits(portPinArray *portPinArrayPointerData, \
portPinArray *portPinArrayPointerClock, int alphaNumbericCharacter)
{
int segmentNumber;
int segmentBit;
int segmentByte, segmentByte1;

int Segment0 = 0b11111100;
int Segment1 = 0b01100000;
int Segment2 = 0b11011010;
int Segment3 = 0b11110010;
int Segment4 = 0b01100110;
int Segment5 = 0b10110110;
int Segment6 = 0b10111110;
int Segment7 = 0b11100000;
int Segment8 = 0b11111110;
int Segment9 = 0b11110110;

int SegmentArray[] = {Segment0, Segment1, Segment2, Segment3, Segment4, \
             Segment5, Segment6, Segment7, Segment8, Segment9};

segmentByte = SegmentArray[alphaNumbericCharacter];

    for (segmentNumber = 0; segmentNumber < 8; segmentNumber++)
    {
    segmentByte1 = segmentByte | (1 << segmentNumber);
    if (segmentByte1 == segmentByte)
      setGpioDataPinHigh01(portPinArrayPointerData);
    else
    setGpioDataPinLow01(portPinArrayPointerData);

        sendGoingPositivePulse(portPinArrayPointerClock);
    }
}

void display1Digit01(portPinArrayPointerArray sevenSegmentPortPinArrayPointerArray, \
int digitNumber)
{
portPinArray *portPinArrayPointerClock;
portPinArray *portPinArrayPointerData;
portPinArray *portPinArrayPointerLatch;

portPinArrayPointerClock = sevenSegmentPortPinArrayPointerArray[SCLK_INDEX];
portPinArrayPointerData  = sevenSegmentPortPinArrayPointerArray[DIN_INDEX];
portPinArrayPointerLatch = sevenSegmentPortPinArrayPointerArray[LATCH_INDEX];

setGpioDataPinLow01(portPinArrayPointerLatch);

setGpioDataPinLow01(portPinArrayPointerClock);

loadSevenSegmentDataBits(portPinArrayPointerData, portPinArrayPointerClock, digitNumber);

setGpioDataPinHigh01(portPinArrayPointerLatch);
}

void display1Digit(int digitNumber)
{
display1Digit01(WhutBoardSevenSegmentLedPortPinArrayPointerArray, digitNumber);
}

// ***********************************************************************
// Function - Display all digits
// ***********************************************************************

void displayAllDigits()
{
int digitNumber;

// initializeAllOutputPins(WhutBoardSevenSegmentLedPortPinArrayPointerArray, \
// MAX_7_SEG_LED_PIN_NUMBER);

    for (digitNumber = 0; digitNumber < 10; digitNumber++)
    {
    display1Digit(digitNumber);
    delayTime(ONE_HALF_SECOND);
    }
}

// ***********************************************************************
// End
// ***********************************************************************





// ***********************************************************************
// key031.h
// ***********************************************************************

#include "config031.h"
#include "delay031.h"
#include "gpio032.h"

// ***********************************************************************
// Key functions
// ***********************************************************************

logicLevelValue getKeyStatus();
void echo1Key01();
void echo1Key();
void testEchoThreeKeys();

// ***********************************************************************
// Function - getKeyStatus
// Input    - keyPortPinArrayPointerArray, keyNumber
// Output   - port pin data bit
// ***********************************************************************

logicLevelValue getKeyStatus(portPinArrayPointerArray keyPortPinArrayPointerArray, \
deviceNumber keyNumber)
{
logicLevelValue keyStatus;
int portNumber;
int pinNumber;
GPIO_TypeDef *gpio_struct_ptr;

keyStatus = getGpioDataPinValue(keyPortPinArrayPointerArray, keyNumber);

return keyStatus;
}

// ***********************************************************************
// Function - echo key by LED
// Input    - keyPinPortArrayPointerArray, keyNumber, ledPinPortArrayPointerArray, ledNumber
// Output   - none
// ***********************************************************************

// *** Echo key by single LED ***

void echo1KeyBySingleLed01(portPinArrayPointerArray keyPortPinArrayPointerArray, \
deviceNumber keyNumber, \
portPinArrayPointerArray ledPortPinArrayPointerArray, \
deviceNumber ledNumber, int echoCount)
{
int count;
logicLevelValue keyStatus;

for (count = 0; count < echoCount; count++)
{
delayTime(ONE_SECOND);

keyStatus = HIGH;
while (keyStatus == HIGH)
{
keyStatus = getKeyStatus(keyPortPinArrayPointerArray, keyNumber);

if (keyStatus == LOW)
{
blink1Led(ledNumber);
delayTime(TWO_SECONDS);
keyStatus = HIGH;
break;
}
}
}
}

void echo1KeyBySingleLed(deviceNumber keyNumber, int ledNumber, int repeatCount)
{
echo1KeyBySingleLed01(*WhutBoardKeyPortPinArrayPointerArray, keyNumber, \
*WhutBoardLedPortPinArrayPointerArray, ledNumber, \
repeatCount);
}


// *** Echo key by 7 segment LED ***

void echo1KeyBy7SegmentLed01(portPinArrayPointerArray keyPortPinArrayPointerArray, \
deviceNumber keyNumber, \
portPinArrayPointerArray sevenSegmentledPortPinArrayPointerArray, \
int digitNumber, int echoCount)
{
int count;
logicLevelValue keyStatus;

for (count = 0; count < echoCount; count++)
{
delayTime(ONE_SECOND);

keyStatus = HIGH;
while (keyStatus == HIGH)
{
keyStatus = getKeyStatus(keyPortPinArrayPointerArray, keyNumber);

if (keyStatus == LOW)
{
// blink1Led(ledNumber);
display1Digit(digitNumber);
delayTime(TWO_SECONDS);
keyStatus = HIGH;
break;
}
}
}
}

void echo1KeyBy7SegmentLed(deviceNumber keyNumber, int digitNumber, int repeatCount)
{
echo1KeyBy7SegmentLed01(*WhutBoardKeyPortPinArrayPointerArray, keyNumber, \
*WhutBoardSevenSegmentLedPortPinArrayPointerArray, digitNumber, \
repeatCount);
}


// ***********************************************************************
// End
// ***********************************************************************