Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to run it on Raspberry Pi Pico? #6

Closed
YuryMalyshev opened this issue Dec 9, 2022 · 6 comments
Closed

How to run it on Raspberry Pi Pico? #6

YuryMalyshev opened this issue Dec 9, 2022 · 6 comments

Comments

@YuryMalyshev
Copy link

Hi,

I'm trying to compile it for Raspberry Pi Pico (RP2040, ARM Cortex-M0+) but I can't get it to work. I'm not sure what I'm doing wrong, maybe my CMakeLists.txt is not properly set up.

My current project structure is as follows:
Project/
├──libraries/
│..├──AFBR-S50-API/
│..│..├──Include/
│..│..│..├──api/
│..│..│..│..├──
│..│..│..│..└── CMakeLists.txt
│..│..│..├──platform/
│..│..│..│..├──
│..│..│..│..└── CMakeLists.txt
│..│..│..├──utility/
│..│..│..│..├──
│..│..│..│..└── CMakeLists.txt
│..│..│..├── argus.h
│..│..│..└── CMakeLists.txt
│..│..├──Lib/
│..│..│..└── < .a files>
│..│..├──Test/
│..│..│..└── < Test files >
│..└── CMakeLists.txt
├── main.c
├── pico_sdk_import.cmake
└── CMakeLists.txt

So, I've put your library into the "libraries" folder and added CMakeLists.txt to each folder.
"CMakeLists.txt" in the "api", "platform", and "utility" is simply

project(api)

target_sources(${PROJECT_NAME} PUBLIC)

target_include_directories(${PROJECT_NAME} INTERFACE
${CMAKE_CURRENT_LIST_DIR} )

Where the project name (in this case "api") is set to the folder name

"CMakeLists.txt" in the "Include" folder is:

project(AFBR)

add_library(${PROJECT_NAME} INTERFACE)

target_include_directories(${PROJECT_NAME} INTERFACE
    ${CMAKE_CURRENT_LIST_DIR}
    ${CMAKE_CURRENT_LIST_DIR}/api
    ${CMAKE_CURRENT_LIST_DIR}/platform
    ${CMAKE_CURRENT_LIST_DIR}/utility
)

target_link_libraries(${PROJECT_NAME} INTERFACE
    ${CMAKE_CURRENT_LIST_DIR}/../Lib/libafbrs50_m0p.a
)

"CMakeLists.txt" in the "libraries" folder is just

add_subdirectory(AFBR-S50-API/Include)

The main "CMakeLists.txt" is:

cmake_minimum_required(VERSION 3.12)

# Pull in SDK (must be before project)
include(pico_sdk_import.cmake)

# set the project name
project(picotest C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS_RELEASE "-O3")

if (PICO_SDK_VERSION_STRING VERSION_LESS "1.3.0")
    message(FATAL_ERROR "Raspberry Pi Pico SDK version 1.3.0 (or later) required. Your version is ${PICO_SDK_VERSION_STRING}")
endif()

# Initialize the SDK
pico_sdk_init()

if (TARGET tinyusb_device)
    add_executable(${PROJECT_NAME}
        main.c
        libraries/AFBR-S50-API/Test/argus_hal_test.c
    )
            
    add_subdirectory(libraries)

    # pull in common dependencies
    target_link_libraries(${PROJECT_NAME} 
	pico_stdlib 
	hardware_spi
	hardware_uart
	hardware_irq
	hardware_gpio
	hardware_flash
	hardware_sync
	hardware_pwm
	hardware_adc
	pico_time
	pico_multicore
	pico_platform
	AFBR
	)
	
	# target_include_directories(${PROJECT_NAME} PUBLIC libraries)
	
	pico_set_binary_type(${PROJECT_NAME} copy_to_ram)

    # enable usb output, disable uart output
    pico_enable_stdio_usb(${PROJECT_NAME} 1)
    pico_enable_stdio_uart(${PROJECT_NAME} 0)

    # create bin and uf2 files
    pico_add_bin_output(${PROJECT_NAME})
    pico_add_uf2_output(${PROJECT_NAME})

elseif(PICO_ON_DEVICE)
    message(WARNING "not building the project because TinyUSB submodule is not initialized in the SDK")
endif()

add_compile_options(-Wall
        -Wno-format          # int != int32_t as far as the compiler is concerned because gcc has int32_t as long int
        -Wno-unused-function # we have some for the docs that aren't called
        -Wno-maybe-uninitialized
        )

My "main.c"

#include "pico/stdio.h"
#include "stdio.h"
#include "stdlib.h"
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "pico/sync.h"
#include "hardware/xosc.h"
#include "pico/multicore.h"
#include "string.h"
#include "pico/platform.h"
#include "hardware/pwm.h"
#include "hardware/gpio.h"

#include "hardware/spi.h"

#include "libraries/AFBR-S50-API/Test/argus_hal_test.h"


int main()
{
  stdio_init_all();
  // a small delay just to be able to read the output of the test
  for(int i = 0; i < 10; i++)
  {
    sleep_ms(1000);
    printf("%d\n", i);
  }
  // init spi
  spi_init(spi1, 10000000);
  spi_set_format(spi1, 8, SPI_CPOL_1, SPI_CPHA_1, SPI_MSB_FIRST);
  gpio_set_function(12, GPIO_FUNC_SPI);
  gpio_set_function(14, GPIO_FUNC_SPI);
  gpio_set_function(15, GPIO_FUNC_SPI);
  gpio_set_function(13, GPIO_FUNC_SIO);
  gpio_set_dir(13, true);
  gpio_put(13, true);

  Argus_VerifyHALImplementation(13);

  while(true)
  {
    sleep_ms(1000);
  }
  return 0;
}

I'm also attaching the project folder if you want to look it at it yourself
AFBR-S50.tar.gz

@YuryMalyshev
Copy link
Author

Alternatively, could you provide the reference to the SPI protocol you use? Like, what kind of commands are available, and what they look like.
For example, in "argus_hal_test.c" I can see some magic numbers were used to configure the sensor. In the function ConfigureDevice, you send 5 bytes uint8_t d2[] = { 0x16, 0x7F, 0xFF, 0x7F, 0xE9 } but it's not clear what these numbers are.

@YuryMalyshev
Copy link
Author

It seems the structure was actually OK. After implementing functions from "platform" folder, I've managed to compile the code.
There are still a couple of problems.

  1. For some reason, the first call to SpiConnectionTest always fails.
  2. TimerTest fails with
+-------+---------+------------+
| count | samples | elapsed us |
+-------+---------+------------+
|     1 |     100 |         10 |
|     2 |     200 |         10 |
|     3 |     300 |         10 |
|     4 |     400 |         10 |
|     5 |     500 |         10 |
|     6 |     600 |         10 |
|     7 |     700 |          9 |
|     8 |     800 |         10 |
|     9 |     900 |         10 |
|    10 |    1000 |         10 |
+-------+---------+------------+
Linear Regression: y(x) = 0E-7 sec * x + 100E-7 sec
ERROR: Time test failed!
The measured time slope does not match the expected value! (actual: 0E-7, expected: 1024E-7, min: 993E-7, max: 1054E-7)

What does it mean?
3. In S2PI_SetIrqCallback I'm not sure on which edge the irq should be called. Rising or falling, or both?
4. SPI read/write operation is blocking. Is it a problem?

@c-berger
Copy link
Contributor

Hi YuryMalyshev,

thanks for the detailed information. I just came to the same result about the missing platform implementation. When porting the API to another platform (as the RP2040), one needs to implement the platform layers for the given platform. This is the main part of porting the API, so you already have made a big leap by doing so.

Are you aware of our porting guides?
Here is a reference porting guide to an STM32 platform:
https://docs.broadcom.com/docs/AFBR-S50-SDK-Porting-Guide-to-Cortex-M4-PG
And here is a generic porting guide with some useful hints you may find helpful:
https://broadcom.github.io/AFBR-S50-API/porting_guide.html

Regarding the new questions:

  1. Can you post the error message of the failed SPIConnectionTest? You can also have a look here: Device Initialization Yields Device Not Connected (Error Code -101)
  2. The timer test depends on the SPI connection as it connects to the device and runs some measurements on the device to obtain a time reference that can be compared to the timer implementation. As long as the SPIConnectionTest fails, the timer test is also bound to fail...
  3. S2PI_SetIrqCallback must triggers on the falling edge.
  4. The API relies on a asynchronous SPI operation. It will generate a new SPI transfers from SPI, GPIO or timer interrupt callbacks and than immediately return and wait for the next callback to happen. It has never been tested if synchronous SPI operations are OK.

Unfortunately, we can not provide a register map for several reasons. One of them is the complexity that is built into the API to generate reasonable measurement values.

Please let me know if you need further help.

Best regards,
Christoph Berger

@YuryMalyshev
Copy link
Author

Thank you for the answer.

Yes, I glanced over the porting guide. The main confusion was due to my mistake with CMake, I didn't link the library properly at first, so functions from api and platform were missing.

  1. The error I get is
ERROR: SPI connection test failed!
Verification of read data is invalid!
read_data[1] = 0, but expected was 1

the subsequent call passes.

Other than that, all tests (except PIT, I don't need it right now) passed now.

@goetzfrv
Copy link
Contributor

Hello Yury,
is everything working now with your Pico porting? Would you mind to share you code?
Appreciate your efforts.
Thank you!

@YuryMalyshev
Copy link
Author

Hello,
There's a bit of a problem with the IRQ line. It fails every now and then, and then everything gets stuck. I think it's a problem with my logic / how I handle the state change. It's probably needed to either use both cores or switch to RTOS to fix it.

I gave up on it for now, it's no longer a priority for us. I'll take another look during/after Christmas holidays.

I'll think about how to share the code because I created a bunch of CMakeLists files all over the place, so I want to clean it up a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants