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, };