Thingy91 How to manually configure SPI chip select pin as GPIO output pin

I am having some issues with the Thingy91 and SPI. I want to configure GPIO0 8 as GPIO_OUTPUT pin.

This is my source code:

#include <stdio.h>
#include <stdlib.h>
#include <zephyr/kernel.h>
#include <zephyr/drivers/spi.h>
#include <zephyr/device.h>
#include <zephyr/drivers/gpio.h>

#define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(main);


// Define the CS pin
#define CS_PIN 8
const struct device *gpio_dev;

int main(void)
{
	int err;
	printk("Program started \n");
	gpio_pin_configure(gpio_dev, CS_PIN, GPIO_OUTPUT);

	if (err < 0)
	{
		printk("GPIO pin configure failed with error %d\n", err);
		return 0;
	}
	k_msleep(1000);
	printk("getting into while loop \n");
	return 0;
}

You can also access my code at github:

https://github.com/krupis/thingy91_spi_test

gpio_configure_bug branch.

It is also important to mention that on the Thing91 nRF52840, Connectivity Bridge application is running. I am only interested in programming nRF9160.

I have read about how to configure CS pin as GPIO from the following post:

 Is it possible to control SPI chip select pin with Zephyr GPIO API? 

and basically copy and pasted the code that has been suggested.

But for me it does not seem to work. The code just halts when gpio_pin_configure(gpio_dev, CS_PIN, GPIO_OUTPUT)is called. I have tried looking at the serial monitor but no logs are coming out even though I have added multiple printk statements.

After launching debugger, I have discovered that the Securefault_hanlder is triggered when the gpio_pin_configure is called:

I have 2 questions

  1. Am I configuring the GPIO correctly? (gpio0 8). If not, could you suggest an alternative way?
  2. Why am I not seeing a single printk statement being printed to the serial console? I have printk("Program started \n"); statement before the gpio_pin_configure call but that never gets printed.
Thanks in advance.
Parents
  • UPDATE

     

    I have tried different method of configuring GPIO pin. Check the code below:

    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/spi.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/gpio.h>
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main);
    
    
    // Define the CS pin
    // #define CS_PIN 8
    // const struct device *gpio_dev;
    
    #define MY_GPIO0 DT_NODELABEL(gpio0)
    #define GPIO0_8_CS 8
    const struct device* gpio0_dev = DEVICE_DT_GET(MY_GPIO0);
    
    int main(void)
    {
    	int err;
    	printk("Program started \n");
    	gpio_pin_configure(gpio0_dev, GPIO0_8_CS, GPIO_OUTPUT);
    
    	if (err < 0)
    	{
    		printk("GPIO pin configure failed with error %d\n", err);
    		return 0;
    	}
    	k_msleep(1000);
    	printk("getting into while loop \n");
    	return 0;
    }
    
    

    The above code seem to work fine and no longer crashed at gpio_pin_conifigure call.

    I believe the method that has been suggested in the post below

     Is it possible to control SPI chip select pin with Zephyr GPIO API? 

    is not even a valid method and should not be used. In the above method, it is not even specified which gpio port to use (gpio0 or gpio1 or others)?

  • Glad to hear it works now. 

    Regarding question two. Did you include the header file for printk? I could not see it when I looked over the code. 

    I will take a look at the case you linked. From a short glance the verified response was not from a Nordic employee and was verified by another user

    Regards

    Runar

  • Thanks for a quick response.

    I was not aware that printk statement requires any include.

    Could it be because I am using CONFIG_LOG_MODE_DEFERRED (i think its the default mode)

    and it simply does not have enough time to process the print statement and send it out to the console as the CPU crashes too fast?

  • It might be that there are some default include for printk in for board. I will have to check, but I know that in our devAcademy course we write that you need to include printk.h. 

    we also write the following "The output of the printk() is not deferred, meaning the output is sent immediately to the console without any mutual exclusion or buffering".  I have replicated the behavior on my end I will need to investigate as it does not make sense for me. I will update the case when I understand why. 

    In your case you are not using any logging, just printk which is a less powerful version of printf. I would recommend using "log_inf/log_err.." as I normally find it more powerful during debugging. I specifically really like the log_dbg do to this ""If you use LOG_DBG(), you can choose not to include that level of logging when you compile the production version of your code."

    Regards

    Runar

     

Reply
  • It might be that there are some default include for printk in for board. I will have to check, but I know that in our devAcademy course we write that you need to include printk.h. 

    we also write the following "The output of the printk() is not deferred, meaning the output is sent immediately to the console without any mutual exclusion or buffering".  I have replicated the behavior on my end I will need to investigate as it does not make sense for me. I will update the case when I understand why. 

    In your case you are not using any logging, just printk which is a less powerful version of printf. I would recommend using "log_inf/log_err.." as I normally find it more powerful during debugging. I specifically really like the log_dbg do to this ""If you use LOG_DBG(), you can choose not to include that level of logging when you compile the production version of your code."

    Regards

    Runar

     

Children
  • Update: 

    The reason "printk" works is that it is included as a part of zephyr/include/zephyr/kernel_includes.h 

    Regards

    Runar

  • Since you mentioned printf and log_dbg, I have tried something out. Please see the source code below:

    #include <stdio.h>
    #include <stdlib.h>
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/spi.h>
    #include <zephyr/device.h>
    #include <zephyr/drivers/gpio.h>
    
    #define LOG_LEVEL CONFIG_LOG_DEFAULT_LEVEL
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(main);
    
    
    // Define the CS pin
    #define CS_PIN 8
    const struct device *gpio_dev;
    
    int main(void)
    {
    	int err;
    	printk("Program started printk\n");
    	printf("Program started pritnf \n");
    	LOG_DBG("Program started log_dbg\n");
    	gpio_pin_configure(gpio_dev, CS_PIN, GPIO_OUTPUT);
    
    	if (err < 0)
    	{
    		printk("GPIO pin configure failed with error %d\n", err);
    		return 0;
    	}
    	k_msleep(1000);
    	printk("getting into while loop \n");
    	return 0;
    }

    with the following prj.conf:

    CONFIG_LOG=y
    CONFIG_SPI=y
    CONFIG_GPIO=y
    
    

    As you can see from the code above, I am trying 3 different print methods (printf, printk, and log_dbg).

    From the serial terminal I see that only printf is being printed before the CPU crashed at the function gpio_pin_configure

    This tells me that printf prints to the console instantly whereas log_dbg and printk is not.

  • Hi Lukas

    I tested your setup on my part. I was not able to recreate what you are seeing. At my side only the printk was printed before the crash. 
    On your end it looks like it might be some corruption since you have the special sign before the printf line. You could also try with an CONFIG_LOG_IMMEDIATE to make it print the log at once. 

    We have also in the past seen usb hubs might affect thing also. 

    There is also a known bug in jlink that can affect you, we have a workaround for it here

    Regards

    Runar

  • Please clarify if you are testing this on the Thingy 91 or some other DK? 

    After adding CONFIG_LOG_MODE_IMMEDIATE=y

    it now prints printf and printk before the crash:
    I think that special character is just some serial data getting flushed out after I program the device. It only appears after I program the device while having the serial port open. It will not appear if I just reboot the device so I dont think that should be an issue.

    It is also very concerning why would you not see the printf being printed. You should definately see printf being printed before the crash if you are using Thingy 91 as there is no reason why you would not.
    Can you confirm if the order of your print statements are as following:
        printk("Program started printk\n");
        printf("Program started pritnf \n");
        LOG_DBG("Program started log_dbg\n");

    We have also in the past seen usb hubs might affect thing also. 
    I plug the Thing91 directly to my laptop so expansion hubs should not be a problem.

    It is very interesting why we both see different results on our identical setups (I assume you tried my project on the Thingy91).
     
    If you did not try my specific project, could you please try it to ensure you are not able to reproduce the issue with my particular prj.conf and etc...
    You need:
    Thingy 91 (Connectivity Bridge application running on the nRF52840 and my program running on the nRF9160)
Related