Invalid pins number

Hello,

I'm currently developing with a nrf52832 (QFABB0) and I have to use pins 16,38,37 and 17 as gpio.

The problem is that when I have an error for pins greater than 32:

In file included from ../nRF5_SDK_15.3.0_59ac345/components/boards/boards.h:43,
                 from ./src/main.cpp:12:
../nRF5_SDK_15.3.0_59ac345/modules/nrfx/hal/nrf_gpio.h: In function 'int main()':
../nRF5_SDK_15.3.0_59ac345/modules/nrfx/hal/nrf_gpio.h:535:28: error: array subscript 38 is above array bounds of 'volatile uint32_t [32]' {aka 'volatile long unsigned int [32]'} [-Werror=array-bounds]
  535 |     reg->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos)
      |     ~~~~~~~~~~~~~~~~~~~~~~~^
In file included from ../nRF5_SDK_15.3.0_59ac345/modules/nrfx/mdk/nrf.h:97,
                 from ../nRF5_SDK_15.3.0_59ac345/components/libraries/util/app_error.h:56,
                 from ../nRF5_SDK_15.3.0_59ac345/components/libraries/timer/app_timer.h:70,
                 from ./src/main.cpp:9:
../nRF5_SDK_15.3.0_59ac345/modules/nrfx/mdk/nrf52.h:2261:19: note: while referencing 'NRF_GPIO_Type::PIN_CNF'
 2261 |   __IOM uint32_t  PIN_CNF[32];                  /*!< (@ 0x00000700) Description collection[0]: Configuration of GPIO
      |                   ^~~~~~~
In file included from ../nRF5_SDK_15.3.0_59ac345/components/boards/boards.h:43,
                 from ./src/main.cpp:12:
../nRF5_SDK_15.3.0_59ac345/modules/nrfx/hal/nrf_gpio.h:535:28: error: array subscript 37 is above array bounds of 'volatile uint32_t [32]' {aka 'volatile long unsigned int [32]'} [-Werror=array-bounds]
  535 |     reg->PIN_CNF[pin_number] = ((uint32_t)dir << GPIO_PIN_CNF_DIR_Pos)
      |     ~~~~~~~~~~~~~~~~~~~~~~~^
In file included from ../nRF5_SDK_15.3.0_59ac345/modules/nrfx/mdk/nrf.h:97,
                 from ../nRF5_SDK_15.3.0_59ac345/components/libraries/util/app_error.h:56,
                 from ../nRF5_SDK_15.3.0_59ac345/components/libraries/timer/app_timer.h:70,
                 from ./src/main.cpp:9:
../nRF5_SDK_15.3.0_59ac345/modules/nrfx/mdk/nrf52.h:2261:19: note: while referencing 'NRF_GPIO_Type::PIN_CNF'
 2261 |   __IOM uint32_t  PIN_CNF[32];                  /*!< (@ 0x00000700) Description collection[0]: Configuration of GPIO
      |                   ^~~~~~~
cc1plus: all warnings being treated as errors

I cannot find anything to change the pin count to 48 (the number of pin on the chip) in the SDK.

Here is the code I'm using to set pins (pins number are specified in the Pin enum):

extern "C" {
#include "app_timer.h"
#include "app_uart.h"
#include "app_util_platform.h"
#include "boards.h"
#include "nordic_common.h"
#include "nrf.h"
#include "nrf_drv_clock.h"
#include "nrf_pwr_mgmt.h"
#include <nrfx_gpiote.h>
#include <radio_config.h>
#include <stdint.h>
#include <string.h>
}

#include "data.h"
#include "uart.h"

enum class Pin {
  Power = 30, // white led
  BleState = 28, // blue led
  FlashState = 29, // red led
  FlashDetect = 31,
  ManualDetect = 27,
  LedPane1 = 16,
  LedPane2 = 38,
  LedPane3 = 37,
  LedPane4 = 17,
  OneWire = 12,
  UNKNOWN,
};

APP_TIMER_DEF(blinkTimer);
APP_TIMER_DEF(flashTimer);
APP_TIMER_DEF(configMode);
APP_TIMER_DEF(sequenceTimer);

static uint32_t packet;
static bool sequenceStarted = false;
int sequenceStep = 0;
bool configTimeout = false;
unsigned int triggerNumber = 0;

static void sendPacket(uint32_t inPacket);
static void gpio_init();
static void init_radio();
void startFlash();
static void timers_init();
void stopOneWire();
void sequence();
void doConfig();

static void sendPacket(uint32_t inPacket) {
  packet = inPacket;
  NRF_RADIO->EVENTS_READY = 0U;
  NRF_RADIO->TASKS_TXEN = 1;

  while (NRF_RADIO->EVENTS_READY == 0U) {
  }

  NRF_RADIO->EVENTS_END = 0U;
  NRF_RADIO->TASKS_START = 1U;

  while (NRF_RADIO->EVENTS_END == 0U) {
  }

  NRF_RADIO->EVENTS_DISABLED = 0U;
  NRF_RADIO->TASKS_DISABLE = 1U;

  while (NRF_RADIO->EVENTS_DISABLED == 0U) {
  }
  packet = 0;
}

static uint32_t readPacket() {
  uint32_t result = 0;

  NRF_RADIO->EVENTS_READY = 0U;
  NRF_RADIO->TASKS_RXEN = 1U;

  while (NRF_RADIO->EVENTS_READY == 0U) {
  }

  NRF_RADIO->EVENTS_END = 0U;
  NRF_RADIO->TASKS_START = 1U;

  while (NRF_RADIO->EVENTS_END == 0U) {
  }

  if (NRF_RADIO->CRCSTATUS == 1U) {
    result = packet;
    packet = 0;
  }
  NRF_RADIO->EVENTS_DISABLED = 0U;
  NRF_RADIO->TASKS_DISABLE = 1U;

  while (NRF_RADIO->EVENTS_DISABLED == 0U) {
  }
  return result;
}

void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name) {
  app_error_handler(0xdeadbeef, line_num, p_file_name);
}

/**
 * @brief make sure the differente clock for the radio are enabled and configure
 * it;
 */
static void init_radio() {
  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
  NRF_CLOCK->TASKS_HFCLKSTART = 1;

  while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
  }

  NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
  NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
  NRF_CLOCK->TASKS_LFCLKSTART = 1;

  while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
  }

  radio_configure();
  NRF_RADIO->PACKETPTR = (uint32_t)&packet;
}

/**
 * @brief Call a function on flashTimer timeout.
 * @param[in] pContext a pointer to the function to call on timeout.
 */
static void flashEndTimerHandler(void *pContext) {
  reinterpret_cast<void (*)()>(pContext)();
}


/**
 * @brief Handle the blinking of the differente leds.
 */
static void blinkTimerHandler(void *pContext) {
  if (!configTimeout) {
    nrf_gpio_pin_toggle(static_cast<uint32_t>(Pin::BleState));
  } else {
    nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::BleState));
  }
}

static void configModeTimerHandler(void *pContext) { configTimeout = true; }

/**
 * @brief Stop the current sequence after the sequenceLength.
 */
static void sequenceTimerHandler(void *pContext) {
  triggerNumber = 0;
  sequenceStep = -1;
  sequenceStarted = false;
}

/**
 * @brief Initialize the differents timers.
 */
static void timers_init() {
  nrf_drv_clock_init();
  nrf_drv_clock_lfclk_request(NULL);

  app_timer_init();
  app_timer_create(&blinkTimer, APP_TIMER_MODE_REPEATED, blinkTimerHandler);
  app_timer_start(blinkTimer, APP_TIMER_TICKS(200), NULL);
  app_timer_create(&flashTimer, APP_TIMER_MODE_SINGLE_SHOT,
                   flashEndTimerHandler);

  app_timer_create(&configMode, APP_TIMER_MODE_SINGLE_SHOT,
                   configModeTimerHandler);
  app_timer_create(&sequenceTimer, APP_TIMER_MODE_SINGLE_SHOT,
                   sequenceTimerHandler);
}

/**
 * @brief Stop all pane and forward the trigger message.
 */
void endFlash() {
  nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::FlashState));
  nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::LedPane1));
  nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::LedPane2));
  nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::LedPane3));
  nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::LedPane4));
  app_timer_start(flashTimer, APP_TIMER_TICKS(250),
                  reinterpret_cast<void *>(&stopOneWire));


  switch (getTrigger()) {
  case Trigger::Radio:
    sendPacket(0x00000001);
    break;
  case Trigger::Manual:
    nrf_gpio_pin_set(static_cast<uint32_t>(Pin::OneWire));
    break;
  default:
    break;
  }
}

/**
 * @brief End the signal on the communication gpio.
 */
void stopOneWire() { nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::OneWire)); }

/**
 * @brief Turn on  all the enabled flash en launch the timers to end the flashes
 * if the mode is not seq, launch the sequence otherwise.
 */
void startFlash() {

  if (sequenceStarted) {
    return;
  }

  if (isSeq()) {
    sequenceStarted = true;
    sequenceStep = -1;
    sequence();
  } else {

    nrf_gpio_pin_set(static_cast<uint32_t>(Pin::FlashState));

    if (isPaneEnabled(0))
      nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane1));

    if (isPaneEnabled(1))
      nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane2));

    if (isPaneEnabled(2))
      nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane3));

    if (isPaneEnabled(3))
      nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane4));

    app_timer_start(flashTimer, APP_TIMER_TICKS(flashLength()),
                    reinterpret_cast<void *>(&endFlash));
  }
}

static void power_management_init() { nrf_pwr_mgmt_init(); }

static void idle_state_handle() { nrf_pwr_mgmt_run(); }

/**
 * @brief gpio initialization
 */
static void gpio_init() {

  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::Power));

  nrf_gpio_cfg_input(static_cast<uint32_t>(Pin::ManualDetect),
                     NRF_GPIO_PIN_PULLDOWN);

  nrf_gpio_cfg_input(static_cast<uint32_t>(Pin::FlashDetect),
                     NRF_GPIO_PIN_PULLDOWN);

  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::BleState));
  
  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::FlashState));
  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::FlashState));
  
  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::OneWire));
  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::OneWire));

  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::LedPane1));
  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::LedPane2));
  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::LedPane3));
  nrf_gpio_cfg_output(static_cast<uint32_t>(Pin::LedPane4));

  /* */
  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane1));
  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane2));
  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane3));
  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::LedPane4));
  /* */
}

/**
 * @brief Convert a pane number to the poin corespondant.
 * @param[in] paneNumber the number of the pane.
 */
Pin paneNumberToPin(int paneNumber) {
  Pin ret;
  switch (paneNumber) {
  case 0:
    ret = Pin::LedPane1;
    break;
  case 1:
    ret = Pin::LedPane2;
    break;
  case 2:
    ret = Pin::LedPane3;
    break;
  case 3:
    ret = Pin::LedPane4;
    break;
  default:
    ret = Pin::UNKNOWN;
    break;
  }
  return ret;
}

/**
 * @brief function that handle the flashing if the mode is sequence, then
 * forward the trigger signal.
 */
void sequence() {
  if (sequenceStep >= 0) {
    nrf_gpio_pin_clear(
        static_cast<uint32_t>(paneNumberToPin(order(sequenceStep))));
  }

  if (++sequenceStep >= 5 || order(sequenceStep) > 3) {
    sequenceStarted = false;
    nrf_gpio_pin_clear(static_cast<uint32_t>(Pin::FlashState));
    switch (getTrigger()) {
      case Trigger::Radio:
        sendPacket(0x00000001);
        break;
      case Trigger::Manual:
        nrf_gpio_pin_set(static_cast<uint32_t>(Pin::OneWire));
        break;
      default:
        break;
    }
    return;
  }

  nrf_gpio_pin_set(static_cast<uint32_t>(Pin::FlashState));
  nrf_gpio_pin_set(static_cast<uint32_t>(paneNumberToPin(order(sequenceStep))));
  app_timer_start(flashTimer, APP_TIMER_TICKS(flashLength()), reinterpret_cast<void *>(&sequence));
}

/**
 * @brief Check if the device is being triggered. 
 */
bool isTriggered() {
  bool ret = false;

  if (isMaster()) {
    ret = nrf_gpio_pin_read(static_cast<uint32_t>(Pin::ManualDetect));
  } else {
    switch (getTrigger()) {
    case Trigger::Manual:
      ret = nrf_gpio_pin_read(static_cast<uint32_t>(Pin::ManualDetect));
      break;
    case Trigger::Radio:
      ret = readPacket() == 0x00000000;
      break;
    case Trigger::Flash:
      ret = nrf_gpio_pin_read(static_cast<uint32_t>(Pin::FlashDetect));
      break;
    default:
      break;
    }
  }

  return ret;
}

int main() {
  gpio_init();
  timers_init();
  power_management_init();
  initFlash();
  readFromFlash();

  doConfig();

  init_radio();

  while (1) {
    if (isTriggered()) {
      if (triggerNumber == 0) {
        app_timer_start(sequenceTimer, APP_TIMER_TICKS(sequenceLength()), nullptr);
      }
      triggerNumber++;
    }
    if ((isMaster() && triggerNumber == 1) || (triggerNumber == orderInSequence())) {
      startFlash();
    }
  }
}

/**
 * brief Handle configuration over BLE step.
 */
void doConfig() {
  initBleUart();
  app_timer_start(configMode, APP_TIMER_TICKS(configDelay()), nullptr);
  while (!configTimeout || isBleConnected()) {
    idle_state_handle();
  }
  stopBleUart();
}

Note that I'm just the developer and I'm not making the PCB using this chip.

Thank you for your help.

Parents Reply Children
No Data
Related