[嵌入式linux] 有点糟心的知合玄铁A210 Melon Pi开发板试用

[复制链接]
16|0
donatello1996 发表于 2026-11-4 18:47 | 显示全部楼层 |阅读模式
收到知合玄铁A210 Melon Pi开发板已经挺久了,我记得有一两个月了,中间驯服这块开发板的过程可谓痛苦至极。。。


先说开发板界面显示的事情,玄铁A210 Melon Pi开发板的GPU驱动不清楚是否正确安装,使用modetest指令无法找到输出设备,知合玄铁论坛也没有给出modetest指令的正确参数,CRTC ID和CONN ID也不清楚,因此只能使用操作系统自带的输出界面来输出,而无法通过代码接管HDMI输出接口:
2.jpg

然后是最基础的GPIO功能,是的没错,使用gpiod指令设置GPIO状态,正确填写gpiochip号和line号,报错:
3.jpg 4.jpg

开发板预留了QSPI排针,但是没有在/dev下映射spidev设备,因此无论是模拟SPI还是硬件SPI都走不通,唯一能通信的手段只剩排针的UART8和USB接口:
5.jpg


好在开发板是有ch340驱动的,可以通过USB接口接串口模块进行通信,保留了最后的一点希望。另外,开发板的i2c-7接口也能正常使用,这算是一堆坏消息里的好消息了:
6.jpg


然后就是所有Linux开发板最最最基础的USB UVC即免驱摄像头功能,是的没错,知合玄铁A210 Melon Pi开发板使用ioctl设置USB UVC摄像头分辨率失败,无法抓取图像。。。我的天。。。


最后还有一个令人绝望的问题,知合玄铁A210 Melon Pi开发板因为跑的是RV64软件架构,VSCode的RomoteSSH插件还没有对RV64软件架构支持,也就是说,无法通过SSH的方式远程保存代码。。。必须要用SFTP这种方式更新代码。


在如此艰巨糟心的条件之下,我也只能草草了事结束试用活动,硬件连接如下:
7.jpg

I2C应用代码:
  1. #define I2C_INTER_DEVICE        "/dev/i2c-7"
  2. int i2c2_fd;
  3. i2c_rdwr_ioctl_data i2c2;

  4. struct bme680_dev gas_sensor;
  5. struct bme680_field_data bme680fd;

  6. int I2C_Device_Read(uint8_t i2c_dev_addr , uint8_t read_data[] , int len , uint8_t reg_addr)
  7. {
  8.     int i;
  9.     if ((i2c2_fd = open(I2C_INTER_DEVICE , O_RDWR))<0)
  10.     {
  11.         printf("Fail to open %s device\n" , I2C_INTER_DEVICE);
  12.         return 1;
  13.     }
  14.     ioctl(i2c2_fd , I2C_TIMEOUT , 2);
  15.         ioctl(i2c2_fd , I2C_RETRIES , 1);

  16.     i2c2.nmsgs = 2;
  17.     i2c2.msgs = (struct i2c_msg*)malloc(i2c2.nmsgs * sizeof(struct i2c_msg));
  18.     if(!i2c2.msgs)
  19.     {
  20.         printf("malloc error\n");
  21.         return 2;
  22.     }
  23.     (i2c2.msgs[0]).len = 1;
  24.     (i2c2.msgs[0]).addr = i2c_dev_addr;
  25.     (i2c2.msgs[0]).flags = 0;
  26.     (i2c2.msgs[0]).buf = (unsigned char*)malloc(1);
  27.     (i2c2.msgs[0]).buf[0] = reg_addr;

  28.     (i2c2.msgs[1]).len = len;
  29.     (i2c2.msgs[1]).addr = i2c_dev_addr;
  30.     (i2c2.msgs[1]).flags = I2C_M_RD;
  31.     (i2c2.msgs[1]).buf = (unsigned char*)malloc(len);
  32.     (i2c2.msgs[1]).buf[0] = 0;
  33.     if(ioctl(i2c2_fd , I2C_RDWR , &i2c2) < 0)
  34.     {
  35.         //printf("Read failed.\n");
  36.         for(i = 0 ; i < i2c2.nmsgs ; i ++)
  37.         {
  38.             free(i2c2.msgs[i].buf);
  39.         }
  40.         free(i2c2.msgs);
  41.         close(i2c2_fd);
  42.         return 3;
  43.     }
  44.     else
  45.     {
  46.         //printf("Read success.\n");

  47.         memcpy(read_data , i2c2.msgs[1].buf , len);

  48.         for(i = 0 ; i < i2c2.nmsgs ; i ++)
  49.         {
  50.             free(i2c2.msgs[i].buf);
  51.         }
  52.         free(i2c2.msgs);
  53.         close(i2c2_fd);
  54.         return 0;
  55.     }
  56. }

  57. int I2C_Device_Write(uint8_t i2c_dev_addr , uint8_t s[] , int len , uint8_t reg_addr)
  58. {
  59.     int i;
  60.     if ((i2c2_fd = open(I2C_INTER_DEVICE , O_RDWR))<0)
  61.     {
  62.         printf("Fail to open i2c-2 device\n");
  63.         return 1;
  64.     }
  65.     ioctl(i2c2_fd , I2C_TIMEOUT , 2);
  66.         ioctl(i2c2_fd , I2C_RETRIES , 1);

  67.     i2c2.nmsgs = 1;
  68.     i2c2.msgs = (struct i2c_msg*)malloc(i2c2.nmsgs * sizeof(struct i2c_msg));
  69.     if(!i2c2.msgs)
  70.     {
  71.         printf("malloc error\n");
  72.         return 2;
  73.     }
  74.         
  75.     i2c2.nmsgs = 1;
  76.     i2c2.msgs[0].len = 1 + len;
  77.     i2c2.msgs[0].addr = i2c_dev_addr;
  78.     i2c2.msgs[0].flags = 0;
  79.     i2c2.msgs[0].buf = (unsigned char*)malloc(1 + len);
  80.     i2c2.msgs[0].buf[0] = reg_addr;
  81.     memcpy(i2c2.msgs[0].buf + 1 , s , len);
  82.     if(ioctl(i2c2_fd , I2C_RDWR , &i2c2) < 0)
  83.     {
  84.         //printf("Write failed.\n");
  85.         for(i = 0 ; i < i2c2.nmsgs ; i ++)
  86.         {
  87.             free(i2c2.msgs[i].buf);
  88.         }
  89.         free(i2c2.msgs);
  90.         close(i2c2_fd);
  91.         return 3;
  92.     }
  93.     else
  94.     {
  95.         //printf("Write success.\n");
  96.         for(i = 0 ; i < i2c2.nmsgs ; i ++)
  97.         {
  98.             free(i2c2.msgs[i].buf);
  99.         }
  100.         free(i2c2.msgs);
  101.         close(i2c2_fd);
  102.         return 0;
  103.     }
  104. }

  105. int8_t user_i2c_write(uint8_t dev_id , uint8_t reg_addr , uint8_t *reg_data , uint16_t len)
  106. {
  107.     I2C_Device_Write(0x77 , reg_data , len , reg_addr);
  108.         return 0;
  109. }

  110. int8_t user_i2c_read(uint8_t dev_id , uint8_t reg_addr , uint8_t *reg_data , uint16_t len)
  111. {
  112.     I2C_Device_Read(0x77 , reg_data , len , reg_addr);
  113.         return 0;
  114. }


QMC5883L地磁指南针代码:
  1. void QMC5883L_Init()
  2. {
  3.         uint8_t data_qmc;
  4.        
  5.         data_qmc = 0x0d;
  6.     I2C_Device_Write(0x0d , &data_qmc , 1 , 0x09);
  7.     I2C_Device_Read(0x0d , &data_qmc , 1 , 0x09);
  8.         printf("QMC5883L 0x09 = 0x%02x.\n" , data_qmc);

  9.     data_qmc = 0x01;
  10.     I2C_Device_Write(0x0d , &data_qmc , 1 , 0x0b);
  11.     I2C_Device_Read(0x0d , &data_qmc , 1 , 0x0b);
  12.         printf("QMC5883L 0x0b = 0x%02x.\n" , data_qmc);
  13.        
  14.         data_qmc = 0x40;
  15.     I2C_Device_Write(0x0d , &data_qmc , 1 , 0x20);
  16.     I2C_Device_Read(0x0d , &data_qmc , 1 , 0x20);
  17.         printf("QMC5883L 0x20 = 0x%02x.\n" , data_qmc);
  18.        
  19.         data_qmc = 0x01;
  20.     I2C_Device_Write(0x0d , &data_qmc , 1 , 0x21);
  21.     I2C_Device_Read(0x0d , &data_qmc , 1 , 0x21);
  22.         printf("QMC5883L 0x21 = 0x%02x.\n" , data_qmc);
  23. }

PAJ7620手势传感器代码:
  1. #define PAJ7620_ADDR_BASE                                0x00
  2. #define PAJ7620_REGITER_BANK_SEL                (PAJ7620_ADDR_BASE + 0xEF)
  3. #define PAJ7620_ID                      0x73
  4. #define PAJ7620_VAL(val, maskbit)                ( val << maskbit )
  5. #define PAJ7620_BANK0                                        PAJ7620_VAL(0,0)

  6. unsigned char paj_init_register_array[][2] =
  7. // Initial Gesture
  8. {
  9.     {0xEF,0x00},
  10.         {0x32,0x29},
  11.         {0x33,0x01},
  12.         {0x34,0x00},
  13.         {0x35,0x01},
  14.         {0x36,0x00},
  15.         {0x37,0x07},
  16.         {0x38,0x17},
  17.         {0x39,0x06},
  18.         {0x3A,0x12},
  19.         {0x3F,0x00},
  20.         {0x40,0x02},
  21.         {0x41,0xFF},
  22.         {0x42,0x01},
  23.         {0x46,0x2D},
  24.         {0x47,0x0F},
  25.         {0x48,0x3C},
  26.         {0x49,0x00},
  27.         {0x4A,0x1E},
  28.         {0x4B,0x00},
  29.         {0x4C,0x20},
  30.         {0x4D,0x00},
  31.         {0x4E,0x1A},
  32.         {0x4F,0x14},
  33.         {0x50,0x00},
  34.         {0x51,0x10},
  35.         {0x52,0x00},
  36.         {0x5C,0x02},
  37.         {0x5D,0x00},
  38.         {0x5E,0x10},
  39.         {0x5F,0x3F},
  40.         {0x60,0x27},
  41.         {0x61,0x28},
  42.         {0x62,0x00},
  43.         {0x63,0x03},
  44.         {0x64,0xF7},
  45.         {0x65,0x03},
  46.         {0x66,0xD9},
  47.         {0x67,0x03},
  48.         {0x68,0x01},
  49.         {0x69,0xC8},
  50.         {0x6A,0x40},
  51.         {0x6D,0x04},
  52.         {0x6E,0x00},
  53.         {0x6F,0x00},
  54.         {0x70,0x80},
  55.         {0x71,0x00},
  56.         {0x72,0x00},
  57.         {0x73,0x00},
  58.         {0x74,0xF0},
  59.         {0x75,0x00},
  60.         {0x80,0x42},
  61.         {0x81,0x44},
  62.         {0x82,0x04},
  63.         {0x83,0x20},
  64.         {0x84,0x20},
  65.         {0x85,0x00},
  66.         {0x86,0x10},
  67.         {0x87,0x00},
  68.         {0x88,0x05},
  69.         {0x89,0x18},
  70.         {0x8A,0x10},
  71.         {0x8B,0x01},
  72.         {0x8C,0x37},
  73.         {0x8D,0x00},
  74.         {0x8E,0xF0},
  75.         {0x8F,0x81},
  76.         {0x90,0x06},
  77.         {0x91,0x06},
  78.         {0x92,0x1E},
  79.         {0x93,0x0D},
  80.         {0x94,0x0A},
  81.         {0x95,0x0A},
  82.         {0x96,0x0C},
  83.         {0x97,0x05},
  84.         {0x98,0x0A},
  85.         {0x99,0x41},
  86.         {0x9A,0x14},
  87.         {0x9B,0x0A},
  88.         {0x9C,0x3F},
  89.         {0x9D,0x33},
  90.         {0x9E,0xAE},
  91.         {0x9F,0xF9},
  92.         {0xA0,0x48},
  93.         {0xA1,0x13},
  94.         {0xA2,0x10},
  95.         {0xA3,0x08},
  96.         {0xA4,0x30},
  97.         {0xA5,0x19},
  98.         {0xA6,0x10},
  99.         {0xA7,0x08},
  100.         {0xA8,0x24},
  101.         {0xA9,0x04},
  102.         {0xAA,0x1E},
  103.         {0xAB,0x1E},
  104.         {0xCC,0x19},
  105.         {0xCD,0x0B},
  106.         {0xCE,0x13},
  107.         {0xCF,0x64},
  108.         {0xD0,0x21},
  109.         {0xD1,0x0F},
  110.         {0xD2,0x88},
  111.         {0xE0,0x01},
  112.         {0xE1,0x04},
  113.         {0xE2,0x41},
  114.         {0xE3,0xD6},
  115.         {0xE4,0x00},
  116.         {0xE5,0x0C},
  117.         {0xE6,0x0A},
  118.         {0xE7,0x00},
  119.         {0xE8,0x00},
  120.         {0xE9,0x00},
  121.         {0xEE,0x07},
  122.         {0xEF,0x01},
  123.         {0x00,0x1E},
  124.         {0x01,0x1E},
  125.         {0x02,0x0F},
  126.         {0x03,0x10},
  127.         {0x04,0x02},
  128.         {0x05,0x00},
  129.         {0x06,0xB0},
  130.         {0x07,0x04},
  131.         {0x08,0x0D},
  132.         {0x09,0x0E},
  133.         {0x0A,0x9C},
  134.         {0x0B,0x04},
  135.         {0x0C,0x05},
  136.         {0x0D,0x0F},
  137.         {0x0E,0x02},
  138.         {0x0F,0x12},
  139.         {0x10,0x02},
  140.         {0x11,0x02},
  141.         {0x12,0x00},
  142.         {0x13,0x01},
  143.         {0x14,0x05},
  144.         {0x15,0x07},
  145.         {0x16,0x05},
  146.         {0x17,0x07},
  147.         {0x18,0x01},
  148.         {0x19,0x04},
  149.         {0x1A,0x05},
  150.         {0x1B,0x0C},
  151.         {0x1C,0x2A},
  152.         {0x1D,0x01},
  153.         {0x1E,0x00},
  154.         {0x21,0x00},
  155.         {0x22,0x00},
  156.         {0x23,0x00},
  157.         {0x25,0x01},
  158.         {0x26,0x00},
  159.         {0x27,0x39},
  160.         {0x28,0x7F},
  161.         {0x29,0x08},
  162.         {0x30,0x03},
  163.         {0x31,0x00},
  164.         {0x32,0x1A},
  165.         {0x33,0x1A},
  166.         {0x34,0x07},
  167.         {0x35,0x07},
  168.         {0x36,0x01},
  169.         {0x37,0xFF},
  170.         {0x38,0x36},
  171.         {0x39,0x07},
  172.         {0x3A,0x00},
  173.         {0x3E,0xFF},
  174.         {0x3F,0x00},
  175.         {0x40,0x77},
  176.         {0x41,0x40},
  177.         {0x42,0x00},
  178.         {0x43,0x30},
  179.         {0x44,0xA0},
  180.         {0x45,0x5C},
  181.         {0x46,0x00},
  182.         {0x47,0x00},
  183.         {0x48,0x58},
  184.         {0x4A,0x1E},
  185.         {0x4B,0x1E},
  186.         {0x4C,0x00},
  187.         {0x4D,0x00},
  188.         {0x4E,0xA0},
  189.         {0x4F,0x80},
  190.         {0x50,0x00},
  191.         {0x51,0x00},
  192.         {0x52,0x00},
  193.         {0x53,0x00},
  194.         {0x54,0x00},
  195.         {0x57,0x80},
  196.         {0x59,0x10},
  197.         {0x5A,0x08},
  198.         {0x5B,0x94},
  199.         {0x5C,0xE8},
  200.         {0x5D,0x08},
  201.         {0x5E,0x3D},
  202.         {0x5F,0x99},
  203.         {0x60,0x45},
  204.         {0x61,0x40},
  205.         {0x63,0x2D},
  206.         {0x64,0x02},
  207.         {0x65,0x96},
  208.         {0x66,0x00},
  209.         {0x67,0x97},
  210.         {0x68,0x01},
  211.         {0x69,0xCD},
  212.         {0x6A,0x01},
  213.         {0x6B,0xB0},
  214.         {0x6C,0x04},
  215.         {0x6D,0x2C},
  216.         {0x6E,0x01},
  217.         {0x6F,0x32},
  218.         {0x71,0x00},
  219.         {0x72,0x01},
  220.         {0x73,0x35},
  221.         {0x74,0x00},
  222.         {0x75,0x33},
  223.         {0x76,0x31},
  224.         {0x77,0x01},
  225.         {0x7C,0x84},
  226.         {0x7D,0x03},
  227.         {0x7E,0x01},
  228. };

  229. #define INIT_REG_ARRAY_SIZE (sizeof(paj_init_register_array)/sizeof(paj_init_register_array[0]))

  230. void PAJ7620_Init()
  231. {
  232.     uint32_t i;
  233.     uint8_t data_paj;
  234.        
  235.         data_paj = PAJ7620_BANK0;
  236.     I2C_Device_Write(PAJ7620_ID , &data_paj , 1 , PAJ7620_REGITER_BANK_SEL);
  237.     I2C_Device_Read(PAJ7620_ID , &data_paj , 1 , PAJ7620_REGITER_BANK_SEL);

  238.     I2C_Device_Read(0x0d , &data_paj , 1 , 0);
  239.         printf("PAJ7620 Init 0 = 0x%02x\n" , data_paj);
  240.     I2C_Device_Read(0x0d , &data_paj , 1 , 1);
  241.     printf("PAJ7620 Init 1 = 0x%02x\n" , data_paj);

  242.     for(i = 0 ; i < INIT_REG_ARRAY_SIZE ; i ++)
  243.     {
  244.         data_paj = paj_init_register_array[i][1];
  245.         I2C_Device_Write(PAJ7620_ID , &data_paj , 1 , paj_init_register_array[i][0]);
  246.     }

  247.         data_paj = PAJ7620_BANK0;
  248.     I2C_Device_Write(PAJ7620_ID , &data_paj , 1 , PAJ7620_REGITER_BANK_SEL);
  249.     I2C_Device_Read(PAJ7620_ID , &data_paj , 1 , PAJ7620_REGITER_BANK_SEL);

  250.     I2C_Device_Read(0x0d , &data_paj , 1 , 0);
  251.         printf("PAJ7620 Init 0 = 0x%02x\n" , data_paj);
  252.     I2C_Device_Read(0x0d , &data_paj , 1 , 1);
  253.     printf("PAJ7620 Init 1 = 0x%02x\n" , data_paj);
  254. }

  255. uint8_t PAJ7620_Read()
  256. {
  257.         uint8_t paj7620_gest = 0;
  258.         I2C_Device_Read(PAJ7620_ID , &paj7620_gest , 1 , 0x43);
  259.         if(paj7620_gest != 0)
  260.         {
  261.                 printf("paj7620_gest = %d.\n" , paj7620_gest);
  262.         }
  263.         return paj7620_gest;
  264. }

串口发送:
  1.    str_uart[0] = 0xaa;
  2.                         str_uart[1] = 0xbb;
  3.                        
  4.                         str_uart[2] = 0x01;
  5.                        
  6.                         str_uart[3] = (bme680fd.temperature >> 8) & 0xff;
  7.                         str_uart[4] = bme680fd.temperature & 0xff;
  8.                        
  9.                         str_uart[5] = (bme680fd.pressure >> 24) & 0xff;
  10.                         str_uart[6] = (bme680fd.pressure >> 16) & 0xff;
  11.                         str_uart[7] = (bme680fd.pressure >> 8) & 0xff;
  12.                         str_uart[8] = bme680fd.pressure & 0xff;
  13.                        
  14.                         str_uart[9] = (bme680fd.humidity >> 24) & 0xff;
  15.                         str_uart[10] = (bme680fd.humidity >> 16) & 0xff;
  16.                         str_uart[11] = (bme680fd.humidity >> 8) & 0xff;
  17.                         str_uart[12] = bme680fd.humidity & 0xff;

  18.                         str_uart[13] = (qmcs_angle_xy_32 >> 8) & 0xff;
  19.                         str_uart[14] = qmcs_angle_xy_32 & 0xff;

  20.                         str_uart[15] = paj7620_gest;
  21.                        
  22.                         str_uart[30] = 0xcc;
  23.                         str_uart[31] = 0xdd;

  24.                         count_uart = write(fd_uart , str_uart , 32);
  25.                         printf("count_uart = %d.\n" , count_uart);
  26.                         if (count_uart < 0)
  27.                         {
  28.                             printf("UART write failed.\n");
  29.                         }
  30.                         tcflush(fd_uart , TCIFLUSH);
  31.                         tcflush(fd_uart, TCOFLUSH);
  32.                         tcflush(fd_uart, TCIOFLUSH);


演示视频:
3306B07B36E087E1DB02082E5805BAC8.jpg



哎总算结束这糟心的试用活动了,立马归还开发板给论坛好好睡个觉。


8FA87A209A96480D7120EAC91AD3C194.jpg
您需要登录后才可以回帖 登录 | 注册

本版积分规则

10

主题

62

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部