sandeepmistry / arduino-nRF5

Arduino Core for Nordic Semiconductor nRF5 based boards
Other
872 stars 278 forks source link

nRF52832 P0.00 and P0.01 cannot be used as GPIO #505

Closed mdellen closed 1 year ago

mdellen commented 1 year ago

I have 1 led connected to both P0.00 and P0.01 on a custom board. The LED turns on, but vaguely and does not respond. (as if the outputs are still set to XL1 and XL2 for the 32.768Khz crystal , which is not available on this board.) When uploading an example .hex file the LED works fine. I have tried this with both digitalWrite and analogWrite.

Steps to reproduce:

In the variant.h (platformio) I have defined the pins:

#define PIN_LED1            (0)         // LED_RED_N(P0.00)
#define PIN_LED2            (1)         // LED_RED_N(P0.01)

In setup I define the pins as output and set the output high.

pinMode(PIN_LED1, OUTPUT);
pinMode(PIN_LED2, OUTPUT);
analogWrite(PIN_LED1, 255);
analogWrite(PIN_LED2, 255);

In the main loop I blink the LED

  delay(1000);
  analogWrite(PIN_LED1, 255);
  analogWrite(PIN_LED2, 255);

  delay(1000);
  analogWrite(PIN_LED1, 0);
  analogWrite(PIN_LED2, 0);

Defining the pin myself does not fix the issue:

    NRF_GPIO->PIN_CNF[PIN_LED1] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) |
                                  (GPIO_PIN_CNF_DRIVE_H0H1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                  (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos) |
                                  (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                  (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);

when I change one of the pins to pin 5 (also a LED) the LED responds as expected. I do not seem to be able to gain control over P0.00 and P0.01, could this be resolved or is there a workaround. Anyone facing the same issue?

carlosperate commented 1 year ago

I haven't checked the code, but it's possible this Arduino Core is using 10-bit values, in which case 255 would be very dim. If you set the value to 1023 are the LEDs brighter?

What do you mean when you say they "do not respond"?

carlosperate commented 1 year ago

I might be wrong about the PWM value, but to simplify the issue let's just look at the normal GPIO, if you use digitalWrite() instead of analogWrite(), what happens?

mdellen commented 1 year ago

@carlosperate thank you for your reply. indeed to simplify the issue lets focus on the digitalWrite().

This works on ALL available pins EXCEPT P0.00 and P0.01. The LED connected to these pins lights up very dim, but does not repond to setting the output signal to HIGH or LOW. this does work on all other pins. P0.00 and P0.01 can also be used for the 32.768KHz XTAL, but I did not enable this, and even explicitly set this to the internal RC.

   // Disable the use of the low frequency crystal oscillator
    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);

It should be possible to use these pins, even on the NRF52832 Development Kit when you disconnect the 32.768KHz Xtal. The hardware is working as the example blink.hex does work. (made using just the NRF SDK)

This is slowly driving me crazy as blinking a LED should not cause so much trouble right... ;)

mdellen commented 1 year ago

I finally managed to fix my own problem. Checked it with the NRF52-DK.

Turns out that the 32KHz xtal was not disabled as suspected. The following fixed the issue.

  // deactivate 32KHz
  NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_RC;  
  NRF_CLOCK->TASKS_LFCLKSTART = 1;
  while(!NRF_CLOCK->LFCLKSTAT);

  pinMode(0, OUTPUT);
  pinMode(1, OUTPUT);

I did do the NRF_CLOCK->LFCLKSRC = CLOCK_LFCLKSRC_SRC_RC; before, but it turns out it does not do anything until you do NRF_CLOCK->TASKS_LFCLKSTART = 1;. I just wait for the RC clock to kick in before I continue, but this is not really needed: while(!NRF_CLOCK->LFCLKSTAT);.

And of course define the pin 0.00 and 0.01 as output. pinMode(0, OUTPUT); pinMode(1, OUTPUT);

Make sure you change the g_ADigitalPinMap[] in the variant.cpp or the nRF52DK if you want to test the pin 0.00 a pin 0.01. Just change these lines:

const uint32_t g_ADigitalPinMap[] = {
  // D0 - D7
  11,
  12,
....

to:

const uint32_t g_ADigitalPinMap[] = {
  // D0 - D7
  0,
  1,
carlosperate commented 1 year ago

I'm glad you were able to resolve your issue @mdellen, and thanks for posting your solution!

As additiona info, the DK board configuration has configured the low frequency crystal: https://github.com/sandeepmistry/arduino-nRF5/blob/5c22636bb588d9afc43fec091dc0807a43f164bb/boards.txt#L348

If this is a custom board, you could select one of the "generic" board types and you'll be able to select a different lf clock configuration from the tools menu:

image