Stuck in API XAxiDma_BdRingFromHw, why doesn't the S2MM Block descriptor's Completed bit Set? - vivado

I am working on Zynq 7z030 and i am trying to receive data on the DDR from the PL side. I am using the AXI DMA SG poll code provided as example by xilinx on SDK. (xaxidma_example_sg_poll.c)
After Configuring DMA -> Setting up the RX channel -> Starting DMA -> I enter the API CheckDmaResult.
Here I call XAxiDma_BdRingFromHw API.
while ((ProcessedBdCount = XAxiDma_BdRingFromHw(RxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}
This API calls Xil_DCacheInvalidateRange which returns and then the Block descriptor status remains always 0. Thus resulting in forever looping of the XAxiDma_BdRingFromHw. The complete bit never sets.
This happens eventhough I see the TREADY of S2MM go high and receive data in ILA(integrated logic analyser on FPGA end/PL end)
main
....
Status1 = CheckDmaResult(&AxiDma);
.....
-> static int CheckDmaResult(XAxiDma * AxiDmaInstPtr)
....
while ((ProcessedBdCount =
XAxiDma_BdRingFromHw(RxRingPtr,
XAXIDMA_ALL_BDS,
&BdPtr)) == 0) {
}
....
-> XAxiDma_BdRingFromHw(XAxiDma_BdRing * RingPtr, int BdLimit,
XAxiDma_Bd ** BdSetPtr)
....
while (BdCount < BdLimit) {
/* Read the status */
XAXIDMA_CACHE_INVALIDATE(CurBdPtr);
BdSts = XAxiDma_BdRead(CurBdPtr, XAXIDMA_BD_STS_OFFSET);
BdCr = XAxiDma_BdRead(CurBdPtr, XAXIDMA_BD_CTRL_LEN_OFFSET);
/* If the hardware still hasn't processed this BD then we are
* done
*/
if (!(BdSts & XAXIDMA_BD_STS_COMPLETE_MASK)) {
break;
}
.....
could someone please suggest possible reasons or directions i should consider to solve this problem.. any and every suggestion would be a great help.
Thanks in advance!

The problem was with the board (ESD damage).
The DDR started receiving data as soon as the board was changed and the following were observed
further in debug config settings the following needed to be ticked on Under Target Setup
Reset entire system
Program FPGA
Under Application tab
Download Application
Stop at 'main'
by Specifying the correct corresponding .elf file in 'Application ' field

Related

HMI Delta Modbus RTU Hex Address (Master)

I'm using DOPSoft to create HMI Application Modbus Master RTU. When I'm using API link.read("{Modbus}5#RW-1") it work fines. But I want to my parameters is flexible for reading multiple slave device with other address, so I used:
local addrLinkMem = string.format("{Modbus}%d#RW-%d", 3, 100);
link.Read(addrLinkMem)
DOPSoft notifies error Program name: Main(10): "addrLinkMem" Element address input error
string.format() is return a string, so addrLinkMem is a string. What I have fault ?
How can I use link.read() without address fixed parameter ?
Thanks very much everyone !!
-- Add initial code here (run once)
while true do
-- Add loop code here (cyclic run)
timeStamp = startTick
readVal1 = link.Read("{Modbus}5#RW-0") --It's work fine
local addrLinkMem = string.format("{Modbus}%d#RW-%d", 3, 100);
readVal2 = link.Read(addrLinkMem) --Program name: Main(10): "addrLinkMem" Element address input error
-- one cycle is 250ms
sys.Sleep(250)
end
``

npm gpio wrong initialized gpio pin value

I am using this gpio library to read the values of gpio pins. This is the code I use to initialize and read gpio pins:
var gpio38 = gpio.export(38, {
direction: gpio.DIRECTION.IN,
interval: 200
});
gpio38.on("change", function(val) {
if(val == 1)
console.log("high")
else {
console.log("low")
}
});
console.log(gpio38.value); //this is where the problem is
As you can see from the code, the gpio pins are set to inputs and will change according to a physical switch. The change function works perfectly and will print high when the switch is on and off when it is turned off.
The problem I am having is that when I try to print the value of gpio38 right after initialization when I leave the switch on, it will always read 0 even though the value of the value of the that gpio pin is 1 (confirmed by reading the voltage of the pin and the Linux file system).
How can I read the correct value of the pin?
To solve this problem, I ended up going outside the library and used Linux commands in my code to ensure the GPIO pins were exported. I also read the value file of the exported GPIO file on the initial start to see the value and then let the library do work in the pin value changes:
exec('echo 38 > /sys/class/gpio/export');
exec('echo 36 > /sys/class/gpio/export');
var pin38_value = parseInt(fs.readFileSync('/sys/class/gpio/gpio38/value', 'utf8'));
var pin36_value = parseInt(fs.readFileSync('/sys/class/gpio/gpio36/value', 'utf8'));

How does a ioctl() call the driver code

I am working on a testing tool for nvme-cli(written in c and can run on linux).
For SSD validation purpose, i was actually looking for a custom command(For e.g. I/O command, write and then read the same and finally compare if both the data are same)
For read the ioctl() function is used as shown in the below code.
struct nvme_user_io io = {
.opcode = opcode,
.flags = 0,
.control = control,
.nblocks = nblocks,
.rsvd = 0,
.metadata = (__u64)(uintptr_t) metadata,
.addr = (__u64)(uintptr_t) data,
.slba = slba,
.dsmgmt = dsmgmt,
.reftag = reftag,
.appmask = appmask,
.apptag = apptag,
};
err = ioctl(fd, NVME_IOCTL_SUBMIT_IO, &io);
Can I to where exactly the control of execution goes in order to understand the read.
Also I want to have another command that looks like
err = ioctl(fd,NVME_IOCTL_WRITE_AND_COMPARE_IO, &io);
so that I can internally do a write, then read the same location and finally compare the both data to ensure that the disk contains only the data that I wanted to write.
Since I am new to this nvme/ioctl(), if there is any mistakes please correct me.
nvme_io() is a main command handler that accepts as a parameter the NVMe opcode that you want to send to your device. According to the standard, you have separate commands (opcodes) for read, write and compare. You could either send those commands separately, or add a vendor specific command to calculate what you need.

Storing Value in Arduino Sent From Python via Serial

I have been trying to send a value from a Python program via serial to an Arduino, but I have been unable to get the Arduino to store and echo back the value to Python. My code seems to match that I've found in examples online, but for whatever reason, it's not working.
I am using Python 3.5 on Windows 10 with an Arduino Uno. Any help would be appreciated.
Arduino code:
void readFromPython() {
if (Serial.available() > 0) {
incomingIntegrationTime = Serial.parseInt();
// Collect the incoming integer from PySerial
integration_time = incomingIntegrationTime;
Serial.print("X");
Serial.print("The integration time is now ");
// read the incoming integer from Python:
// Set the integration time to what you just collected IF it is not a zero
Serial.println(integration_time);
Serial.print("\n");
integration_time=min(incomingIntegrationTime,2147483648);
// Ensure the integration time isn't outside the range of integers
integration_time=max(incomingIntegrationTime, 1);
// Ensure the integration time isn't outside the range of integers
}
}
void loop() {
readFromPython();
// Check for incoming data from PySerial
delay(1);
// Pause the program for 1 millisecond
}
Python code:
(Note this is used with a PyQt button, but any value could be typed in instead of self.IntegrationTimeInputTextbox.text() and the value is still not receieved and echoed back by Arduino).
def SetIntegrationTime(self):
def main():
# global startMarker, endMarker
#This sets the com port in PySerial to the port with the Genuino as the variable arduino_ports
arduino_ports = [
p.device
for p in serial.tools.list_ports.comports()
if 'Genuino' in p.description
]
#Set the proper baud rate for your spectrometer
baud = 115200
#This prints out the port that was found with the Genuino on it
ports = list(serial.tools.list_ports.comports())
for p in ports:
print ('Device is connected to: ', p)
# --------------------------- Error Handling ---------------------------
#Tell the user if no Genuino was found
if not arduino_ports:
raise IOError("No Arduino found")
#Tell the user if multiple Genuinos were found
if len(arduino_ports) > 1:
warnings.warn('Multiple Arduinos found - using the first')
# ---------------------------- Error Handling ---------------------------
#=====================================
spectrometer = serial.Serial(arduino_ports[0], baud)
integrationTimeSend = self.IntegrationTimeInputTextbox.text()
print("test value is", integrationTimeSend.encode())
spectrometer.write(integrationTimeSend.encode())
for i in range(10): #Repeat the following 10 times
startMarker = "X"
xDecoded = "qq"
xEncoded = "qq"
while xDecoded != startMarker: #Wait for the start marker (X))
xEncoded = spectrometer.read() #Read the spectrometer until 'startMarker' is found so the right amound of data is read every time
xDecoded = xEncoded.decode("UTF-8");
print(xDecoded);
line = spectrometer.readline()
lineDecoded = line.decode("UTF-8")
print(lineDecoded)
#=====================================
spectrometer.close()
#===========================================
#WaitForArduinoData()
main()
First, this is a problem:
incomingValue = Serial.read();
Because read() returns the first byte of incoming serial data reference. On the Arduino the int is a signed 16-bit integer, so reading only one byte of it with a Serial.read() is going to give you unintended results.
Also, don't put writes in between checking if data is available and actual reading:
if (Serial.available() > 0) {
Serial.print("X"); // Print your startmarker
Serial.print("The value is now ");
incomingValue = Serial.read(); // Collect the incoming value from
That is bad. Instead do your read immediately as this example shows:
if (Serial.available() > 0) {
// read the incoming byte:
incomingByte = Serial.read();
That's two big issues there. Take care of those and let's take a look at it after those fundamental issues are corrected.
PART 2
Once those are corrected, the next thing to do is determine which side of the serial communication is faulty. Generally what I like to do is determine one side is sending properly by having its output show up in a terminal emulator. I like TeraTerm for this.
Set your python code to send only and see if your sent values show up properly in a terminal emulator. Once that is working and you have confidence in it, you can attend to the Arduino side.

Raw audio playback in Allegro 5

I'm writing a MOD player, trying to playback a sample using Allegro5 raw stream capabilities, I can't figure out the exact init parameters for the stream to play the loaded sample data from the mod file.
This is what I have:
xf::ModLoader ml;
ml.loadFromFile("C:\\Users\\bubu\\Downloads\\agress.mod");
// getSampleLength() returns # of data words
int sample_length = ml.getSampleLength(1) * 2;
const int8_t* sample_data = ml.getSampleData(1);
ALLEGRO_MIXER* mixer = al_get_default_mixer();
ALLEGRO_AUDIO_STREAM* stream = al_create_audio_stream(1, sample_length, 8363, ALLEGRO_AUDIO_DEPTH_INT8, ALLEGRO_CHANNEL_CONF_1);
al_attach_audio_stream_to_mixer(stream, mixer);
al_set_audio_stream_gain(stream, 0.7f);
al_set_audio_stream_playmode(stream, ALLEGRO_PLAYMODE_ONCE);
al_set_audio_stream_playing(stream, true);
al_set_audio_stream_fragment(stream, (void*)sample_data);
al_drain_audio_stream(stream);
First of all, freq param is hardcoded for the test (8363Hz), but, playing back at the specified frequency I don't get what I expect, and al_drain_audio_stream() gets stuck forever playing garbage in a loop...
Any help would be appreciated.
At the very least, you need to be calling al_get_audio_stream_fragment before you call al_set_audio_stream_fragment. Typically you'd feed these streams in a while loop, while responding to the ALLEGRO_EVENT_AUDIO_STREAM_FRAGMENT event. See the ex_saw example in the Allegro's source for some sample code: https://github.com/liballeg/allegro5/blob/master/examples/ex_saw.c

Resources