Dear all,
I am having issues trying to use axi uart from with a microblaze using the pynqmicroblaze library.
I made my own block design and custom overlay following all connections according to the PYNQ MicroBlaze Subsystem. See Pics.
First I built the project in Vitis and program the microblaze using JTAG in vitis in debug mode. It works perfectly, i.e., the axi uart peripherals receive the data I send correctly.
The problem comes when I use the pynq overlay and the from pynq.lib import PynqMicroblaze
library to use the uBlaze subsystem. I follow the steps, program the microblaze writing the memory and now the Axi uart peripherals receive garbage…
I attach python code and code in microblaze.
from pynq.lib import PynqMicroblaze
from pynq import PL
import struct
import time
#reload object from file
fd = open(r'/home/xilinx/base_drone.pkl', 'rb')
ip_dict = pickle.load(fd)
fd.close()
# Check dictionaries for names
ip_dict = PL.ip_dict
gpio_dict = PL.gpio_dict
intr_dict = PL.interrupt_pins
mb_info = {'ip_name': 'iop_ub0/axi_bram_ctrl',
'rst_name': 'mb_iop_ub0_reset'
# 'intr_pin_name': 'iop_ub0/dff_en_reset_vector_0/q',
# 'intr_ack_name': 'mb_iop_ub0_intr_ack'
}
uBlaze_PROGRAM = "/home/xilinx/droneUb_fw.bin"
uBlaze_obj = PynqMicroblaze(mb_info, uBlaze_PROGRAM)
uBlaze_MEM = ip_dict["iop_ub0/axi_bram_ctrl"]
MAILBOX_OFFSET = int(uBlaze_MEM["parameters"]["C_S_AXI_BASEADDR"],0)
MAILBOX_BGN = 0x0000FF00
MAILBOX_END = 0x0000FFFF
MAILBOX_4BYTES = 0x4
# Addresses
MAILBOX_CMD_ADDR = MAILBOX_END - (MAILBOX_4BYTES - 0x1)
MAILBOX_ADDR = MAILBOX_END - (MAILBOX_4BYTES*2 - 0x1)
# Commands
RESET = 0x1
UPDATE_VALUES = 0x3
# uBlaze_obj.program
uBlaze_obj.write(MAILBOX_CMD_ADDR, RESET)
while (uBlaze_obj.read(MAILBOX_CMD_ADDR, 1) != 0):
time.sleep(0.001)
print("pass")
flag = 1
while (flag):
time.sleep(1)
uBlaze_obj.write(MAILBOX_CMD_ADDR, UPDATE_VALUES)
reg = uBlaze_obj.read(MAILBOX_BGN + MAILBOX_4BYTES*0, 4+25)
value = reg[0:4]
print(value)
converted = [int(x) for x in reg[5:29]]
print(converted)
flag = 0
/***************************** Include Files *********************************/
#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#include "../include/pynq_ublaze/uart.h"
//#include "i2c.h"
//#include "ads111x.h"
// Call the library
//#include "common/mavlink.h"
/************************** Constant Definitions *****************************/
// #define DEBUG_MAV
#define MASK_32BITS 0xFFFFFFFF
// Uart definitions
#define uart_device_id_0 0U
#define uart_device_id_1 1U
#define uart_buff_size 16
#define uart_space 32U
#define uart_end_of_line 10U
// i2c definitios
#define i2c_device_id_0 0U
#define sniffbot_nh3_addr 0x49
// Mailbox definitions
// command from A9 to MB0
// command from A9 to MB0
#define MAILBOX_CMD_ADDR (*(volatile uint32_t *)(0x0000FFFC))
// address of MB0
#define MAILBOX_ADDR (*(volatile uint32_t *)(0x0000FFF8))
#define MAILBOX_DATA(x) (*(volatile uint32_t *)(0x0000FF00+((x)*4)))
#define MAILBOX_ADDR_FLOAT (*(volatile float *)(0x0000FFF8))
#define MAILBOX_DATA_FLOAT(x) (*(volatile float *)(0x0000FF00+((x)*4)))
/* Command format
* bit[0] : MP issued command when 1
* bit[1] : Read/Write => 0 : Python requests write
* 1 : Python requests read
*/
// Command arrived from Zynq
#define UPDATE_VALUES 0x01
// Gas Defines
#define CH_GAS 65
/************************** Struct Definitions ******************************/
struct gas_64ch_struct{
uart uart_device;
uint8_t msg[25];
uint8_t flag = 0;
uint8_t new_data = 0;
uint8_t uart_cont = 0;
uint8_t ch_cont = 0;
float values[CH_GAS];
};
typedef gas_64ch_struct gas_64ch_struct;
typedef gas_64ch_struct *gas_64ch;
/************************** Function Prototypes ******************************/
// Gas Functions
void gas_begin(gas_64ch _self, uint16_t uart_device);
void gas_read_incoming(gas_64ch _self);
void gas_update_values(gas_64ch _self);
/************************** Variable Definitions *****************************/
#ifdef DEBUG_MAV
int msgid_hist[255];
uint8_t msgid_cont = 0;
#endif
//uint8_t gas_flag = 0;
//float gas_data[65];
/******************************************************************************/
/**
*
* Main function
*
*
*******************************************************************************/
// Launch the serial port in setup
int main() {
#ifdef DEBUG_MAV
memset(msgid_hist,-1,255*sizeof(msgid_hist[0]));
#endif
// Create Gas Object
gas_64ch gas_ptr;
gas_begin(gas_ptr, uart_device_id_1);
// Start i2c device
//i2c gas_i2c = i2c_open_device(i2c_device_id_0);
//i2c_reset(gas_i2c);
// Start ads1115
//ads111x my_nh3 = ads111x_configure(gas_i2c, sniffbot_nh3_addr);
//uint16_t nh3_value[4] = {0,0,0,0};
//uint8_t channel = 0;
// infinite loop
while(1){
/* Command format
* bit[0] : MP issued command when 1
* bit[1] : Read/Write => 0 : Python requests write
* 1 : Python requests read
*/
// Command arrived from Zynq
uint8_t cmd = MAILBOX_CMD_ADDR;
switch(cmd){
case UPDATE_VALUES:
{
// write out reading, reset mailbox
gas_update_values(gas_ptr);
MAILBOX_CMD_ADDR = 0x0;
break;
}
default:
{
// otherwise continue updating
MAILBOX_CMD_ADDR = 0x0;
// Gas data update
gas_read_incoming(gas_ptr);
// NH3 sensor
//nh3_value[channel] = ads111x_value(my_nh3,channel);
//channel++;
//if (channel > 3)
//channel = 0;
break;
}
}
}
return 0;
}
//----------------------------------------------------------------
void gas_read_incoming(gas_64ch _self){
if (uart_rx_empty(_self->uart_device) == 0){
uint8_t c;
uart_read(_self->uart_device, &c, 1);
if (_self->flag == 1){
_self->msg[_self->uart_cont] = c;
_self->uart_cont++;
if (c == ' '){
float gas_f = atof((const char *)_self->msg);
_self->values[_self->ch_cont] = gas_f;
_self->ch_cont++;
}
}
if (c == uart_end_of_line){
_self->flag = 1;
_self->uart_cont = 0;
_self->ch_cont = 0;
_self->new_data = (_self->ch_cont == CH_GAS)? 1 : 0;
}
_self->uart_cont = (c == ' ')? 0 : _self->uart_cont;
}
}
//----------------------------------------------------------------
void gas_update_values(gas_64ch _self){
for (uint16_t cont_mail = 0; cont_mail<CH_GAS; cont_mail++){
MAILBOX_DATA_FLOAT(cont_mail) = _self->values[cont_mail];
}
}
//---------------------------------------------------------------
void gas_begin(gas_64ch _self, uint16_t uart_device){
// Start uart devices
_self->uart_device = uart_open_device(uart_device);
uart_reset(_self->uart_device);
// Start Variables
_self->flag = 0;
_self->new_data = 0;
_self->uart_cont = 0;
_self->ch_cont = 0;
memset(_self->msg, 0, sizeof(_self->msg));
memset(_self->values, 0, sizeof(_self->values));
}
has anyone else had this issue?
Please help. I am very desperate
FYI, I use PYNQ 2.6 and Vivado 2020.1