Forum Discussion

ETang2's avatar
ETang2
Icon for Occasional Contributor rankOccasional Contributor
1 day ago

NiosV and juart-terminal

I had a project which works fine under niosII. I upgrade all the project with niosv and all seems fine except printing values in juart-terminal.

Here is the main code : 

#include <stdio.h>

#include "system.h"

#include "altera_avalon_pio_regs.h"

#include <altera_avalon_i2c.h>

#include <unistd.h>

#include <string.h>





int main()

{

 

  //*

 

  ALT_AVALON_I2C_DEV_t *i2c_dev;  //pointer to instance structure

  alt_u8 txbuffer[20];

  alt_u8 rxbuffer[20];

  float co2Concentration = 0;

  float temperature = 0;

  float humidity = 0;

  alt_u32 co2U32 = 0;

  alt_u32 tempU32 = 0;

  alt_u32 humU32 = 0;




  ALT_AVALON_I2C_STATUS_CODE status;

 

    i2c_dev = alt_avalon_i2c_open("/dev/i2c"); //Ouverture du périphérique i2c et récupération d'un pointeur

    if (NULL==i2c_dev)

    {

        printf("Error: Cannot find /dev/i2c\n");

        return 1;

    }

    //set the address of the device using

 

      alt_avalon_i2c_master_target_set(i2c_dev,0x61); //Définition de l'adresse du composant adressé 0x61 pour le SCD30

      txbuffer[0]=0x00; txbuffer[1]=0x10; txbuffer[2]=0x00; txbuffer[3]=0x00; txbuffer[4]=0x81; //Remplissage du buffer pour configurer le SDC30 en Continous measurement

      status=alt_avalon_i2c_master_tx(i2c_dev,txbuffer, 5,ALT_AVALON_I2C_NO_INTERRUPTS); //Envoi du buffer au composant

      if (status!=ALT_AVALON_I2C_SUCCESS) return 1; //FAIL



  while(1)

      {



      txbuffer[0]=0x02; txbuffer[1]=0x02;  //Remplissage du buffer pour déterminer si les données sont prêtes

      alt_avalon_i2c_master_tx(i2c_dev,txbuffer, 2,ALT_AVALON_I2C_NO_INTERRUPTS); //Envoi du buffer au composant

      rxbuffer[1]=0x00;

 

      usleep(3000); // Il faut attendre au moins 3ms avant de demander la réponse

      alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 3,ALT_AVALON_I2C_NO_INTERRUPTS); //Récupération de la réponse du composant si rxbuffer[1]==0x01 alors les données sont prêtes



      if(rxbuffer[1]==0x01)

      {

      txbuffer[0]=0x03; txbuffer[1]=0x00;  //Remplissage du buffer pour la lecture des données

      alt_avalon_i2c_master_tx(i2c_dev,txbuffer, 2, ALT_AVALON_I2C_NO_INTERRUPTS); //Envoi du buffer de lecture et récupération des données

      usleep(3000); //Wait 3ms before data available

      alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 18,ALT_AVALON_I2C_NO_INTERRUPTS); //Read datas

      co2U32 = (alt_u32)((((alt_u32)rxbuffer[0]) << 24) | (((alt_u32)rxbuffer[1]) << 16) | (((alt_u32)rxbuffer[3]) << 8) | ((alt_u32)rxbuffer[4]));

 

      tempU32 = (alt_u32)((((alt_u32)rxbuffer[6]) << 24) | (((alt_u32)rxbuffer[7]) << 16) | (((alt_u32)rxbuffer[9]) << 8) | ((alt_u32)rxbuffer[10]));

 

      humU32 = (alt_u32)((((alt_u32)rxbuffer[12]) << 24) | (((alt_u32)rxbuffer[13]) << 16) | (((alt_u32)rxbuffer[15]) << 8) | ((alt_u32)rxbuffer[16]));

      memcpy(&co2Concentration, &co2U32, sizeof(co2Concentration));

      memcpy(&temperature, &tempU32, sizeof(temperature));

      memcpy(&humidity, &humU32, sizeof(humidity));

      }

      printf("---------------------------------------------------------\n");

      printf("SCD30\n");

      printf("Concentration de CO2 : %f ppm\n",co2Concentration);

      printf("Température : %.1f °C\n",temperature);

      printf("Humidité relative : %.1f %% \n",humidity);

      usleep(500000);

}

 

}

I put a breakpoint just before the printf and the values are good : 

but when i print the values in the juart-terminal : 

I can't figure out why the printf does not work as i expect.

Someone could help me to understand this problem ?

Thanks

Eric

5 Replies

  • LiangYuG_Altera's avatar
    LiangYuG_Altera
    Icon for Occasional Contributor rankOccasional Contributor

    Hi ETang2​ 

    I copied and ran similar code as yours.
    However, rather than I2C access (which I don't have), my code directly initialize the numbers in your example.

    The memcpy is successful in replacing the values from 0 to valid values.
    And juart-terminal prints the correct values.


    Could it be possible that you need to change 

    usleep(3000);
    alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 3,ALT_AVALON_I2C_NO_INTERRUPTS);

    to

    while(1) {
          usleep(3000);
          alt_avalon_i2c_master_rx(i2c_dev,rxbuffer, 3,ALT_AVALON_I2C_NO_INTERRUPTS);

          if(rxbuffer[1]==0x01) break;
    }

    When you use breakpoint, there is sufficient delay for alt_avalon_i2c_master_rx() to return rxbuffer[1] = 0x01 at the first attempt.

    However, when you let the application to run normally, usleep(3000) is not enough to get rxbuffer[1] = 0x01.
    Perhaps it is only possible after a few attempts.
    Thus, co2U32, tempU32, and humU32 remains at 0 due to rxbuffer[1] = 0x0.
    Which leads to memcpy 0 into the printed variables, that is also 0.

    To proof this phenomena, you can define different initial value between the printed variables & intermediary variables. This can help to understand whether it is a memcpy or rxbuffer issue.

    float co2Concentration = 888;
    float temperature = 888;
    float humidity = 888;
    alt_u32 co2U32 = 0;
    alt_u32 tempU32 = 0;
    alt_u32 humU32 = 0;

    Regards,
    Liang Yu

  • ETang2's avatar
    ETang2
    Icon for Occasional Contributor rankOccasional Contributor

    Hi LiangYuG_Altera​ 

    Thank you for your reply.

    I think it's not a problem with rxbuffer[1] = 0x01 because the values in the debug window are good. So that seems that the memcopy were right.

    As i put the first breakpoint at the first printf("SCD30\n"); the code before this brekpoint should be executed with the same time as usual and the values are good. The problem is when after this breakpoint i execute the code step by step the printf print the wrong values in juart-terminal. It seems also that there is print problem as the accentuated character "é for example" are not printed correctly. 

    Regards

    Eric

  • LiangYuG_Altera's avatar
    LiangYuG_Altera
    Icon for Occasional Contributor rankOccasional Contributor

    Hi ETang2​ ,

    The problem is when after this breakpoint i execute the code step by step the printf print the wrong values in juart-terminal.

    Noted, sorry for misinterpreting your first post.
    You are right that there is something fishy here.

    • Breakpoint before printf shows printed variables are memcpy correctly from intermediary value.
    • Execute the code step-by-step, and yet the printed variables shows 0.  

    Please allow me some time to think this through.

     

    On the 2nd issue:

    It seems also that there is print problem as the accentuated character "é for example" are not printed correctly. 

    I believe it is due to the default code page of your Windows Command Prompt. Nios V Command Shell follows the default code page.

    Can you check your code page by typing this command in the niosv-shell?

    If the results is 437, then this code page is unable to print é. The character é is stored as two bytes (0xC3 0xA9). Code Page 437 tries to read these as two separate characters (like ├⌐).

    To change from Code Page 437 to UTF-8, 

    In my previous comment, I was running my experiment in Linux.
    And Linux terminal supports UTF-8 by default (unlike Windows Command Prompt).

    Regards,
    Liang Yu

  • LiangYuG_Altera's avatar
    LiangYuG_Altera
    Icon for Occasional Contributor rankOccasional Contributor

    Hi ETang2​ ,

    Can you add this line of code after the %f prints?
    I wonder if your system's printf (%f) is affected by newlib library configuration.

    printf("Raw Decimal: %ld\n", *(alt_u32*)&co2Concentration);

    Example result:



    Regards,
    Liang Yu

  • ETang2's avatar
    ETang2
    Icon for Occasional Contributor rankOccasional Contributor

    Hi LiangYuG_Altera​ 

    Changing the code page solve the accentuated problem.

    I had the code line you proposed but i'm not sure to understand the result : 

    Regards

    Eric