raspberrypi / pico-sdk

BSD 3-Clause "New" or "Revised" License
3.67k stars 913 forks source link

uart0 setup #1587

Closed nrhint closed 9 months ago

nrhint commented 9 months ago

This program should pass through uart communication from a gps module from adafruit to the computer. There are two distinct problems/bugs. When I first read the uart I get a null char even when nothing is coming from the GPS (tested by removing the uart pins from the pico) there is a null char (int 0) in the buffer. This might be normal behavior however I could not find it documented. The second problem is using other pins for uart0. I read several things online and several ways to change it. The way that I am trying right now is in the cmake file where I set the ports. This method did not work for me. I also tried to override the defined values with #define PICO_DEFAULT_UART_TX_PIN 16 \n #define PICO_DEFAULT_UART_RX_PIN 18 which also had no effect.

Here is the code that I am using:

main.cpp

// Nathan Hinton

#include <iostream>
#include <stdio.h>
#include <stdint.h>
#include <string>
#include "pico/stdlib.h"
#include "hardware/uart.h"

#define GPS_UART_TX 19
#define GPS_UART_RX 16

// #define PICO_DEFAULT_UART_TX_PIN GPS_UART_RX
// #define PICO_DEFAULT_UART_RX_PIN GPS_UART_TX

#define GPS_BAUD_RATE 9600

#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
#define PMTK_Q_RELEASE "$PMTK605*31"

int main() {
    stdio_init_all();
    stdio_usb_connected();
    sleep_ms(5000);
    std::cout << "Printing setup info:" << std::endl;
    std::cout << "Init: " << uart_init(uart0, GPS_BAUD_RATE) << std::endl;
    std::cout << "is uart0 enabled: " << uart_is_enabled(uart0) << std::endl;
    std::cout << "uart instance: " << uart_get_index(uart0) <<std::endl;
    // std::cout << "Sending commands to get info from the module:" << std::endl;
    // uart_puts(uart0, PMTK_SET_NMEA_UPDATE_10HZ);
    // uart_puts(uart0, PMTK_SET_NMEA_OUTPUT_ALLDATA);
    // uart_puts(uart0, PMTK_Q_RELEASE);
    // std::string gps_line;
    gpio_init(0);
    gpio_init(1);
    gpio_set_function(0, GPIO_FUNC_UART); //TX
    gpio_set_function(1, GPIO_FUNC_UART); //RX
    std::cout << "Now waiting to get data from the uart:" << std::endl;
    sleep_ms(1000);
    while (true) {
        // Pass through the gps strings to the computer
        std::cout << "Got: " << uart_getc(uart0) << std::endl;
        // uart_put(uart0, 'c');

        // sleep_ms(100);
    }
}

CMakeLists.txt

# What CMake to start at
cmake_minimum_required(VERSION 3.12)

# Include the subsidiary .cmake file to get the SDK
include(/work/pico_ice/tooling/pico-sdk/pico_sdk_init.cmake)

# Set the name and version of the project
project(uart_gps CXX C ASM)

# Link the Project to a source file (step 4.6)
add_executable(uart_gps)

# Initalise the SDK
pico_sdk_init()

target_sources(uart_gps PRIVATE src/main.cpp)

target_compile_definitions(uart_gps PRIVATE 
    PICO_DEFAULT_UART_TX_PIN=16
    PICO_DEFAULT_UART_RX_PIN=19
    )

# Link the Project to an extra library (pico_stdlib)
target_link_libraries(uart_gps PRIVATE pico_stdlib hardware_pio)

# Enable USB, UART output
pico_enable_stdio_usb(uart_gps 1)
# pico_enable_stdio_uart(uart_gps 0)

# Enable extra outputs
pico_add_extra_outputs(uart_gps)

build.sh

## Nathan Hinton

# mkdir -p build && cd build

cmake .. && make && cp uart_gps.uf2 /media/nathan/RPI-RP2/ && sleep 2 && screen /dev/ttyACM0 

The device I am using is a pico-ice which also has an icefpga on the same board but I am not using any of those features. I am happy to keep trying things and providing information. I have created a copy of the project at this point and can try different things. I do not have a ton of experience here so I would not be suppurised if I am doing something wrong. Another random tack on question, where is the best place for documentation? I have looked online and found a ton of different things but many of them do not agree and have different functions and features (I assume partly from the many variants of boards that use the pico chip)

(edited by lurch to fix the formatting of the code-blocks)

peterharperuk commented 9 months ago

It looks like you should ask for help on the forum. PICO_DEFAULT_UART_TX_PIN appears to only be used for stdio as far as I can see. Your code is close but is hardcoding the gpios of course.

gpio_init(0);
gpio_init(1);
gpio_set_function(0, GPIO_FUNC_UART); //TX
gpio_set_function(1, GPIO_FUNC_UART); //RX

You need to check section "1.4.3. GPIO Functions" to know which gpios you can use for rx/tx etc.

lurch commented 9 months ago

where is the best place for documentation?

The official documentation for Pico and RP2040 can be found at https://www.raspberrypi.com/documentation/microcontrollers/

When I first read the uart I get a null char even when nothing is coming from the GPS

That may be due to #1125 (or something similar?)

And WRT adding your #define PICO_DEFAULT_UART_TX_PIN to the C code, note that you need to do this before you #include any files, because https://github.com/raspberrypi/pico-sdk/blob/master/src/boards/include/boards/pico.h does

#ifndef PICO_DEFAULT_UART_TX_PIN
#define PICO_DEFAULT_UART_TX_PIN 0
#endif
nrhint commented 9 months ago

Perfect, thanks for the help. I tracked it down to some board issues and missing documentation for the board that I was using. The pinout of the board was not matching the documentation which I discovered when looking at the schematic and I was using pins that were not uart capable.