This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF9160 GPIO problem on custom board

Shalom!

We have a nRF9160 custom board on which I cannot switch some of the IO lines.

For example we have two leds, P0.9 an P.10 but only P0.9 works. The hardware guy reports the P0.10 output does not change when I toggle the output while debugging. I tried moving the led to P0.30 & P0.31 also without success. Also I need to change a uart1's rx and tx lines in some scenarios when it is not used. In this case I do not call uart_dev = device_get_binding("UART_1"), but want to just clear both lines. I am evidently doing something wrong or missing something. The gpio APIs all report no errors and in the debugger I see that the pin numbers are correct.

Isn't the uart initialed by Zepyr only on calling its binding? I need to change IO on the fly to save power of course. I am new to Zephyr. I have all of the pins I plan to manipulate defined in the board's dts file in the zephyr\boards directory. Can I switch pins that are not in this file? Do I need to add something to my ns overlay? I do not know why P0.9 works but P0.10 does not if it is a security error.

I have a project\child_image\spm\prj.conf file which have a CONFIG_GPIO define. I tried changing it but it does not help. Maybe this is just for the bootloader?

Is there a way in the SES IDE to see the GPIO status at a breakpoint or single stepping? Most IDEs have this option. I am using v1.6.0.

nrf9160axion_nrf9160_common.dtsnrf9160axion_nrf9160ns.overlay

Thanks David

Parents
  • Hello,

     

    Isn't the uart initialed by Zepyr only on calling its binding?

     No, the UART driver is initialized during pre-kernel initialization. device_get_binding("UART_1") just returns the struct for the UART1 binding.

     

    Can I switch pins that are not in this file?

     Do you want to change the pins dynamically? That's not possible as far as I know.

     

    Maybe this is just for the bootloader?

     Yes, sort of. It is just valid for the Secure Partition Manager.

     

    Is there a way in the SES IDE to see the GPIO status at a breakpoint or single stepping?

     Can't you just put the GPIO register on watch? I haven't tried this, but I think it should work.

Reply
  • Hello,

     

    Isn't the uart initialed by Zepyr only on calling its binding?

     No, the UART driver is initialized during pre-kernel initialization. device_get_binding("UART_1") just returns the struct for the UART1 binding.

     

    Can I switch pins that are not in this file?

     Do you want to change the pins dynamically? That's not possible as far as I know.

     

    Maybe this is just for the bootloader?

     Yes, sort of. It is just valid for the Secure Partition Manager.

     

    Is there a way in the SES IDE to see the GPIO status at a breakpoint or single stepping?

     Can't you just put the GPIO register on watch? I haven't tried this, but I think it should work.

Children
  • Shalom!

     In the ncs\vx.y.y\zephyr\boards\arm\ directory, I duplicated the nrf9160dk_nrf9160 with our custom board's name and changing its contents to work with our board. I may have evidently missed something or need to add an overlay or conf file somewhere, since it looks to me that I have a conflict between P0.10 for example and some dk defined pin somewhere else.

    Is there a SES project build output files which shows the pins used?

    Basically, I use uar0,uart1,ADC,I2C for EPROM and temperature chip, SPI for the external flash and lsm6dsl chip.

    All seem to work. I have basic working code that we would like to deploy in the field for cellular network availability evaluation.

    I need to have the ability to use all of the limited port pins but this is not an immediate show stopper. It has to be a definition somewhere in Zephyr I would think. I need to advance somehow on this issue.

    Now the prototype is battery operated and I read the threads about disabling the uart0 & uart1 when sleeping.

    I have defined both uart0 and uart1. I tried disabling uart1 by the following code but EVENTS_RXTO never goes high stalling at the while(NRF_UARTE1_NS->EVENTS_RXTO == 0); line.

    I can see in the debugger, in the callback a UART_RX_BUF_RELEASED and then an almost immediate UART_RX_BUF_REQUEST.

      //---------------------------------------------------------------------------
      // Low power
      //  When putting the system in low power and the peripheral is not needed, 
      // lowest possible power consumption is achieved by stopping, and then disabling the peripheral.
      // The STOPTX and STOPRX tasks may not be always needed (the peripheral might already be stopped), 
      // but if STOPTX and/or STOPRX is sent, software shall wait until the TXSTOPPED and/or RXTO event is received in response,
      // before disabling the peripheral through the ENABLE register.
      //---------------------------------------------------------------------------
      NRF_UARTE1_NS->TASKS_STOPRX=1;
      while(NRF_UARTE1_NS->EVENTS_RXTO == 0);
      NRF_UARTE1->EVENTS_RXTO = 0;
    
      NRF_UARTE1_NS->TASKS_STOPTX = 1;
      while(NRF_UARTE1_NS->EVENTS_TXSTOPPED == 0);
      NRF_UARTE1_NS->EVENTS_TXSTOPPED = 0;
    
      NRF_UARTE1_NS->ENABLE = 0;
      NRF_UARTE1_NS->PSEL.TXD = 0xFFFFFFFF;
      // Clear BLE Txd P0.25  
      NRF_P0_NS->OUTCLR = (1 << 25);
    

    Could it be that I am missing a proj_xx.conf definition?

    I tried both with  and without uart1 initialized at startup.

    I have the bootloader integrated into my code for FOTA. It does not need to be serially updated.

    Currently I use uart0 for system debug printk and for output my own debug information which is very useful.

    uart0 is also used a direct serial connection to configure the end unit. All of this works.

    Do I need to do anything about the other modules (ADC,I2C,SPI)  when not used and want to conserve power?

    I understand that Zephyr puts the nRF9160 into sleep mode when nothing is needed to be done.

    I wait for a semaphore that is given in a 1 second timer handler.

    Can I read uart0's rx line by GPIO to see if it is active in order to reactivate uart0 for a direct connection configuration session?

    Next week I hope that our hardware guy will be able to see how much current is being drawn in this state.

    I am using the latest v1.6.0 setup.

    I tried putting NRF_UARTE1->EVENTS_RXTO  in the SES watch window but it was unknown so I it does not seem that it will work also for the GPIO registers. Maybe the SES team could add this.

  • I have been reading every nRF9160 post I could find and tried their uart conf defines.

    After setting the following resolves the while(NRF_UARTE1_NS->EVENTS_RXTO == 0) problem.

    CONFIG_UART_NRFX=y
    CONFIG_UART_INTERRUPT_DRIVEN=y

    All of the other questions are still open and I would like to know what other uart defines should I also add.

    Also we need the CMSIS libraries and it seems to work but adds a ton of functions that are not even called.

    Is there a way that the linker will remove them or should I just select all of the files I need in a new directory (bad I know).

    CONFIG_CMSIS_DSP=y
    CONFIG_CMSIS_DSP_SUPPORT=y
    CONFIG_CMSIS_DSP_FASTMATH=y
    CONFIG_CMSIS_DSP_COMPLEXMATH=y
    CONFIG_CMSIS_DSP_STATISTICS=y
    CONFIG_CMSIS_DSP_TRANSFORM=y

    Thank you David

  • This morning I found that if I define only

    CONFIG_UART_NRFX=y

    CONFIG_UART_INTERRUPT_DRIVEN=y

    uart_callback_set() returns -ENOTSUP. so I cannot use the callback to read incoming bytes using the callback.

    If I define both async and interrupt as below while(NRF_UARTE1_NS->EVENTS_RXTO == 0); hangs.

    CONFIG_UART_ASYNC_API=y
    CONFIG_UART_NRFX=y
    CONFIG_UART_INTERRUPT_DRIVEN=y

    How do I get around this?

    How can I read incoming bytes without the callaback.

    Thanks David

  • After this morning's integration session, I can report that the GPIO P0.30 & P0.31 problem was really a custom hardware schematic pdf error in which the header was numbered backwards. I guess this was previously resolved when I added correct custom board overlays. Sorry about this.

     I also performed some current draw testing.

    ADC:

     I left the ADC in the overlay file  "okay" but did not reference it in my code and the current was about 900ua.

     I called adc_channel_setup() and adc_read_async() every 3 minutes and the current was about 1000ua.

     I set the ADC in the overlay file "disabled" and the current was also 900ua.

     The base line current was when one uart was not stopped so may be the ADC is not being disabled automatically.

    Uart0 & Uart1:

     At startup I just disabled uart1 as below:

      //---------------------------------------------------------------------------
      // Low power
      //  When putting the system in low power and the peripheral is not needed, 
      // lowest possible power consumption is achieved by stopping, and then disabling the peripheral.
      // The STOPTX and STOPRX tasks may not be always needed (the peripheral might already be stopped), 
      // but if STOPTX and/or STOPRX is sent, software shall wait until the TXSTOPPED and/or RXTO event is received in response,
      // before disabling the peripheral through the ENABLE register.
      //---------------------------------------------------------------------------
      NRF_UARTE1_NS->TASKS_STOPRX=1;
    #if defined(CONFIG_UART_INTERRUPT_DRIVEN)
      while(NRF_UARTE1_NS->EVENTS_RXTO == 0);
    #endif
      NRF_UARTE1->EVENTS_RXTO = 0;
    
      NRF_UARTE1_NS->TASKS_STOPTX = 1;
      while(NRF_UARTE1_NS->EVENTS_TXSTOPPED == 0);
      NRF_UARTE1_NS->EVENTS_TXSTOPPED = 0;
    
      NRF_UARTE1_NS->ENABLE = 0;
      NRF_UARTE1_NS->PSEL.TXD = 0xFFFFFFFF;
      //---------------------------------------------------------------------------
      // Must change TXD to output low in order that BLE chip will not create a current drain
      // Clear BLE Txd P0.25  
      //---------------------------------------------------------------------------
      NRF_P0_NS->OUTCLR = (1 << 25);
      // Clear BLE Rxd P0.24  
      NRF_P0_NS->OUTCLR = (1 << 24);
      //---------------------------------------------------------------------------
      // Must change RXD to output low in order that BLE chip will not create a current drain
      //---------------------------------------------------------------------------
      ami_board_ConfigPin( AMI_BOARD_OUT_BLE_RXD,GPIO_OUTPUT_LOW);
    

     When after using uart0, when sleeping I did nothing, I got the 900ua baseline current.

     When after using uart0, when sleep I performed similar to the code above only for uart0, I got a 480ua to 490ua draw.

     Again I use a timer that wakes the program up once a second and if nothing is needed to be done goes back to sleep.

     I will open a new ticket for the current drawing issue.

     If you could continue to see why it seems that not only used DSP files are being linked, I will not open a separate ticket.

    Thank you David

Related