Index of the Moto Mods Developer project:
Moto Mods Developer Part 1 - Getting Started - Virtual Machine Setup and Linux Install
Moto Mods Developer Part 2 - Getting Started - SDK Setup & Android Studio Install
Moto Mods Developer Part 3 - Firmware Setup
Moto Mods Developer Part 4 - Getting Started - Make Build-Folder, add Utility and OS files
Moto Mods Developer Part 5 - Flashing Firmware with MDK Utility
Moto Mods Developer Part 6 - Blinking an LED on the Moto Mods Perfboard
Moto Mods Developer Part 7 - Modifying the C file for the perfboard LED
Moto Mods Developer Part 8 - Configure Nuttx
Moto Mods Developer Part 9 - Updating the Hardware Manifests file
Moto Mods Developer Part 10 - Cont’d Configure and Compile Nuttx
Moto Mods Developer Part 11 - Load newly created Nuttx Firmware onto Reference Board
Moto Mods Developer Part 12 - Soldering the Test Points to use the perfboard
Moto Mods Developer Part 13 - Making custom App to control the Firmware
After the tools are all setup, there is a file structure in Linux that we build the target firmware with. We will be modifying Motorola’s “Hello World” example to blink an LED. This example modifies the C file that runs the built in LED on the Reference Moto Mod when the switch in MDK utility is turned ON. Motorola give us a few configurations as an example of using Nuttx. First we need to copy and example configuration to a new folder, this is so we have a folder for our project with the “blinky” configuration.
We will create a new target for build called “blinky”
$ cd $BUILD_TOP/nuttx/nuttx/configs/hdk/muc
$ mkdir blinky
$ cp base_powered/* blinky/
The folder is created
We will configure these files later, next we have to modify the stm32_modsraw_blinky.c file to blink the right pin on the Moto Mods perfboard. We can also adjust the blink timing by modifying some #defines. The file is located in our project folder ./nuttx/nuttx/configs/hdk/muc/src
Before we edit the C file. We should create a backup of the original, copy the file to the same folder and it should automatically save it as “stm32_modsraw_blinky (copy).c”
Open the original “stm32_modsraw_blinky.c”. Inside the C file, we can see which header files are used for this file. What we want to do is modify this file so that we can activate a pin on the perfboard, turn it on and off with the timing setup. First we have to make sure the pin is setup properly. Located in the ./nuttx/nuttx/configs/hdk/muc/include folder is a header file that defines the variable pin names for the board, called mods.h
Already located in “stm32_modsraw_blinky.c” is a pin named “GPIO_MODS_DEMO_ENABLE” this is used as an example in the code. It is assigned to GPIO pin PG10. We will use this as the blinky pin. The unmodified C file blinks the “GPIO_MODS_LED_DRV_3” pin which is the pin that drives the built-in LED on the Reference Moto Mod as pictured below:
PG10 is a general GPIO pin that is open for our use. This is according to the STM32 Micro pinout chart provided by Motorola, shown below.
BLINKY CODE::::
/*
* Copyright (c) 2016 Motorola Mobility, LLC.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <errno.h>
#include <debug.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arch/board/mods.h>
#include <nuttx/arch.h>
#include <nuttx/device.h>
#include <nuttx/device_raw.h>
#include <nuttx/power/pm.h>
#include "stm32_tim.h"
#define BLINKY_ACTIVITY 10
#define BLINKY_TIM 6
#define BLINKY_TIM_FREQ 1000
#define BLINKY_PERIOD 1000
#define LED_ON 0
#define LED_OFF 1
static struct stm32_tim_dev_s *tim_dev;
static int blinky_timer_handler(int irq, FAR void *context)
{
uint8_t new_val;
pm_activity(BLINKY_ACTIVITY);
STM32_TIM_ACKINT(tim_dev, 0);
new_val = gpio_get_value(GPIO_MODS_LED_DRV_3) ^ 1;
gpio_set_value(GPIO_MODS_LED_DRV_3, new_val);
llvdbg("new_val=%d\n", new_val);
return 0;
}
static void blinky_timer_start(void)
{
gpio_set_value(GPIO_MODS_DEMO_ENABLE, 1);
if (!tim_dev) {
dbg("BLINKY\n");
tim_dev = stm32_tim_init(BLINKY_TIM);
DEBUGASSERT(tim_dev);
STM32_TIM_SETPERIOD(tim_dev, BLINKY_PERIOD);
STM32_TIM_SETCLOCK(tim_dev, BLINKY_TIM_FREQ);
STM32_TIM_SETMODE(tim_dev, STM32_TIM_MODE_PULSE);
STM32_TIM_SETISR(tim_dev, blinky_timer_handler, 0);
STM32_TIM_ENABLEINT(tim_dev, 0);
} else {
dbg("ignore\n");
}
}
static void blinky_timer_stop(void)
{
gpio_set_value(GPIO_MODS_DEMO_ENABLE, 0);
if (tim_dev) {
dbg("STOP\n");
STM32_TIM_DISABLEINT(tim_dev, 0);
stm32_tim_deinit(tim_dev);
tim_dev = NULL;
gpio_set_value(GPIO_MODS_LED_DRV_3, LED_OFF);
} else {
dbg("ignore\n");
}
}
static int blinky_recv(struct device *dev, uint32_t len, uint8_t data[])
{
if (len == 0)
return -EINVAL;
if (data[0] == 0 || data[0] == '0')
blinky_timer_stop();
else
blinky_timer_start();
return 0;
}
static int blinky_register_callback(struct device *dev,
raw_send_callback callback)
{
/* Nothing to do */
return 0;
}
static int blinky_unregister_callback(struct device *dev)
{
/* Nothing to do */
return 0;
}
static int blinky_probe(struct device *dev)
{
gpio_direction_out(GPIO_MODS_LED_DRV_3, LED_OFF);
gpio_direction_out(GPIO_MODS_DEMO_ENABLE, 0);
return 0;
}
static struct device_raw_type_ops blinky_type_ops = {
.recv = blinky_recv,
.register_callback = blinky_register_callback,
.unregister_callback = blinky_unregister_callback,
};
static struct device_driver_ops blinky_driver_ops = {
.probe = blinky_probe,
.type_ops = &blinky_type_ops,
};
struct device_driver mods_raw_blinky_driver = {
.type = DEVICE_TYPE_RAW_HW,
.name = "mods_raw_blinky",
.desc = "Blinky LED Raw Interface",
.ops = &blinky_driver_ops,
};