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

VirtualBox_Moto Mods Development_08_04_2017_16_48_42.png

 

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:

 

20170322_230233.jpg

 



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