For a while, I had been working on my first “Real” embedded system code on an ARM Cortex m4 microprocessor, the MK60N512 , which comes with the NXP towerkit, TWRK60N512 , and obviously, my first task was to make at least one LED blink on the board. Seeing as I was used to the easy way out, (read Ardu… 🙂 ), I didn’t think it would be such a huge task. But as it turns out, there is a whole LOT of things that needed to be done before actually making the first program. Luckily I had an instructor and the oh so glorious Youtube.
Ok enough with the quests and conquests story. If you would like to work on the Cortex m4 processors on a ready board/ tower you need a couple of things. These include
- The microprocessor data sheet
- The board’s schematics
- The board’s user guide
- The peripheral modules quick reference guide.
The data sheet shows all available registers, the memory map of the general K60 micro-controller. Schematics show the routing of the micro-controller pins in the printed circuit board, this is especially useful because it will help you know which pin is connected to what external circuitry. The user guide just gives the general overview of the kit, the features what can be used and for what purpose. The quick reference guide gives a summary of some configurations possible on the board and some examples as code snippets, just to show how one may program the board.
To begin with, I chose the orange LED. From the schematics, we see that it is on PTA11 (meaning port A pin 11). We need to activate port A (PORT will be explained below) by enabling its clock. This is called clock gating (I’m going to call it clocking the port). Clock gating enables us to activate ONLY the peripherals of the micro-controller that we need to use, leaving all the other peripherals inactive which reduces overall power consumption. From the data sheet, the clock gating for port A is done under the System Integration Module (SIM), in the System Clock Gating Control register 5 (SIM_SCGC5) bit 9. This is done by the code below. But we can skip this step because it’s already done in the board bring-up code ( in system_k60.c)
SIM_SCG5 |= (SIM_SCG5_PORT_A_MASK);
PORT is the port control and interrupt module. As of now we are only interested in the port control bit because our simple task does not require an interrupt. Each pin of the micro-controller can be configured for a number of alternate functions. From the data sheet, we can see that we can configure a port pin to any supported alternate function, select and enable pull-up/down resistors and so on using the pin control register PCR. More specifically, PORTA_PCR11, because that’s the pin we’re using.
Our next course of action is therefore to configure pin 11 of port A to the GPIO (General Purpose Input Output) function. Then activate the pull-up/ pull-down resistor and which will allow us to select either of the two. In my case, I selected the pull down resistor, which made the micro-contoller a current sink rather than source to the LED.
PORTA_PCR11 |= (PORT_PCR_MUX(0x1) | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK );
And then finally, we need to configure the directionality of the GPIO pin.
Since we have already configured our pin to GPIO, and GPIO is an entity on its own, we then go to the gpio A Port Data Direction Register, GPIOA_PDDR. Directionality simply means determining whether the pin is an output or an input pin. Obviously we need to see some output through our LED, so we only only need to set the pin to output data. And we are done with the initialization of the gpio.
GPIOA_PDDR |= (uint32_t)1<<11;
On to the main function. After initializing our gpio, we only now need to concentrate on blinking our LED. Since we need the LED to blink continuously, we need to write data to pin 11 at regular (or irregular depending on how you like it) intervals, but over an infinite time. To do this we need a loop that always evaluates as true, and inside this loop, we write data to the output register for pin 11. Luckily, the gpio has a Port Toggle Output Register (PTOR) which enables the data output register for the pin to be toggled between 1 and 0 meaning that we don’t have to keep setting and clearing the data output register to switch the LED on and off.
So we write to this specific register to enable the toggle function. After this, we need a delay long enough for the human to perceive. The micro-controller works in the order of MHz, the human eyes sees a maximum of 50hz…. I’ll just leave that there for you to calculate how much time to include in the delay 🙂 . We will therefore have something like
// write to the port registers to blink the orange LED.
and oh your Code, your LED should blink 🙂 , (well, mine did) ! You can fork the entire project on my github , to put it into practice. Feel free to tweak the code and tinker with the rest of the LEDs