Implement high impedance 'Z' input output property with chisel - fpga

My board (apf27) has a processor (i.MX27) and a FPGA (Spartan3A) that communicate through a "memory bus" called WEIM in proc datasheet.
I want to transfer data from the FPGA to the processor. I managed to do it with a simple Output() IO :
val io = IO(new Bundle {
...
val data = Output(UInt(16.W))
val oen = Input(Bool())
...
I can read data from the processor, but that "lock" the bus. I have to release it for the nand component also present on it.
To release it I can use the signal oen (output enable) but I can't assign a high impedance value like 'Z' in Verilog/VHDL to 'release' it.
What is the right way to do it in Chisel3 ? I saw something called 'AnalogRawModule" in chisel3 github is it the things to use ?

Analog is what you're looking for. It is basically an escape to allow bidirectional wires and other signals that aren't really supported by Chisel to still connect through your Chisel design.
Here's an example:
import chisel3._
import chisel3.experimental.Analog
class AnalogBlackBox extends BlackBox {
val io = IO(new Bundle {
val bus = Analog(32.W)
})
}
class AnalogModule extends Module {
val io = IO(new Bundle {
val bus = Analog(32.W)
})
val inst = Module(new AnalogBlackBox)
inst.io.bus <> io.bus
}
object AnalogDriver extends App {
chisel3.Driver.execute(args, () => new AnalogModule)
}
You can't drive Analog-type wires in Chisel and unfortunately you can't do concatenation or bit select (although we should support that), but you can at least connect signals through. If you need to do any kind of bit selection or concatenation, you need to do that in a BlackBox.

Related

Developing Generic AXI4 Peripheral with Chisel

I want to develop a generic AXI4 peripheral with Chisel. Can I use the Rocket-Chip's AMBA library for this purpose? I could only find the document in the link below on this subject;
MMIO-Peripherals
However, the example in this document is designed to be used with the Rocket-Chip. I want to develop a standalone AXI4 peripheral.
Your question mentions following:
I want to develop a standalone Axi4 peripheral
When I had started developing AXI4 interfaces in Chisel, my starting point was the Chisel official documentation where they start with a typical Verilog peripheral using AXI4 for a write channel as following:
module my_module(
// Write Channel
input AXI_AWVALID,
output AXI_AWREADY,
input [3:0] AXI_AWID,
input [19:0] AXI_AWADDR,
input [1:0] AXI_AWLEN,
input [1:0] AXI_AWSIZE,
// ...
);
To this end, the Chisel Bundle would be as following:
class VerilogAXIBundle(val addrWidth: Int) extends Bundle {
val AWVALID = Output(Bool())
val AWREADY = Input(Bool())
val AWID = Output(UInt(4.W))
val AWADDR = Output(UInt(addrWidth.W))
val AWLEN = Output(UInt(2.W))
val AWSIZE = Output(UInt(2.W))
// The rest of AW and other AXI channels here
}
// Instantiated as
class my_module extends RawModule {
val AXI = IO(new VerilogAXIBundle(20))
}
Although the aforementioned example is trivial but this was helpful for me to start writing generic AXI4 interfaces in Chisel.
Having said that, I have also used some of the following resources to develop AXI interfaces in Chisel:
AXI-in-Chisel
AXI interfaces-in-Chisel

How to connect multiple RC522 RFID Reader to Raspberry PI?

I want to know if it is possible to connect multiple RC522 to one Raspberry PI, if yes how do we do it? I read in some articles that with CS(chip select) pin we can control Readers, but the CS pin is not present on RC522 I have.
Can you please help me?
Chip Select (CS) is referred to as SS or NSS in some of the RFC522 documentation, is that the issue? If so, connect your CS0 to NSS on one module, CS1 to the NSS on the other, and you can use both modules on the same SPI bus.
If you need more devices than that, you could switch to the I2C interface. In I2C mode, a number of the pins on the chip become address selects, so you can put a whole bunch of them on the same I2C bus. The data sheet for the chip is always helpful with this sort of information. Section 8.1, "Digital interfaces" may be particularly helpful.
In I2C mode, you have 5 bits of addressing, so you can put up to 32 devices on the bus.
Posted this answer before on the raspberry pi stackexchange.
I'll just repost it here for visibility.
You can use the RST Pins to select the reader you want to use. Connect all the other pins in parallel (see schematic below). Just set all the RST pins to low, except the one on the pin you want to use. Set that one to high. Then initialize SPI, read/write, and close SPI again.
I wrote a more detailed explanation here.
This is the schematics and code I made:
Schematic for 2 readers
Schematic for 4 readers
Code to run it all (using pimylifeup's MFRC522-Python Library):
import RPi.GPIO as GPIO
from mfrc522 import SimpleMFRC522
import spidev
class NFC():
def __init__(self, bus=0, device=0, spd=1000000):
self.reader = SimpleMFRC522()
self.close()
self.bus
self.boards = {}
self.bus = bus
self.device = device
self.spd = spd
def reinit(self):
self.reader.READER.spi = spidev.SpiDev()
self.reader.READER.spi.open(self.bus, self.device)
self.reader.READER.spi.max_speed_hz = self.spd
self.reader.READER.MFRC522_Init()
def close(self):
self.reader.READER.spi.close()
def addBoard(self, rid, pin):
self.boards[rid] = pin
def selectBoard(self, rid):
if not rid in self.boards:
print("readerid " + rid + " not found")
return False
for loop_id in self.boards:
GPIO.output(self.boards[loop_id], loop_id == rid)
return True
def read(self, rid):
if not self.selectBoard(rid):
return None
self.reinit()
cid, val = self.reader.read_no_block()
self.close()
return val
def write(self, rid, value):
if not self.selectBoard(rid):
return False
self.reinit()
self.reader.write_no_block(value)
self.close()
return True
if __name__ == "__main__":
nfc = NFC()
nfc.addBoard("reader1",5)
nfc.addBoard("reader2",6)
data = nfc.read("reader1")
nfc.write("reader2",data)

How to debug akka streams flows?

When I drop a breakpoint somewhere in method processLine, debugger does not stop at the line. It executes as if there is not any breakpoint .Is debugging akka streams flows somewhat different, how can i solve this issue?
val stream = source.
map( csvLine => A.processLine(csvLine)).
runWith(Sink)
I have had similar issues with ScalaIDE.
My solution has generally been to isolate my "business logic" from any akka dependencies:
//no akka imports required
case class Tweet(val author : String, val body : String)
def validAuthor(author : String) : Boolean = {
author.trim().size > 0 && !author.equalsIgnoreCase("jk_rowling") //breakpoint works here
}
Then my asynchronous code becomes simple calls to the buz logic:
import akka.stream.scaladsl.{Source, Sink}
val source : Source[Tweet,_] = ???
val flow = source.filter(validAuthor)
.runWith(Sink foreach println)
The IDE then obeys breakpoints in the buz logic, e.g. within validAuthor.

"input is undefined" error when using WebSockets in Elm

I'm trying to set up a simple example using WebSockets in Elm, but I keep getting the run time error "input is undefined". The console does not give me any line number in my elm file or anything like that.
I was trying to use WebSockets in a large project, and I kept getting the error "a is undefined", so I decided to make this small example to try and isolate the problem.
I wrote some code that receives messages containing numbers from the websocket. It increments the numbers, and then sends the new numbers back out over the web socket. The server does the same thing, sending back the number incremented by 1 to the client.
Here is the elm code:
import Graphics.Element (Element)
import Signal
import Signal (Signal)
import Text
import Window
import WebSocket
import String
type State = Num Int
| StateErr String
input : Signal String
input =
WebSocket.connect "ws://localhost:4567/test" sendToServer
sendToServer : Signal String
sendToServer =
Signal.dropRepeats
(Signal.dropIf (\str -> str == "") "" (Signal.map formatReply state))
formatReply : State -> String
formatReply state =
case state of
Num n -> toString n
StateErr str -> ""
stepState : String -> State -> State
stepState str state =
case (String.toInt str) of
Ok n -> Num (n + 1)
Err str -> StateErr str
display : (Int,Int) -> State -> Element
display (w,h) state = Text.asText state
state : Signal State
state =
Signal.foldp stepState (Num 0) input
main : Signal Element
main =
Signal.map2 display Window.dimensions state
I tested the server side, and it's working fine, so I definitely do not think that the server is causing the issue.
When I tried the code in Firefox, I get "input is undefined". When I run it in Chrome, I get "Cannot read property 'kids' of undefined".
In Chrome, upon looking at the stack trace it seems that when the code goes to run, input is undefined. Is this a bug with the WebSocket library?
I'm very new to using Elm, so I'd appreciate any help/advice on using websockets.
I learned that the cause of my troubles, is that as of now the WebSockets library in elm is not fully implemented. I also learned that I can accomplish my goals using ports, and then implementing the websocket in javascript.
I added the following javascript to my html file:
var game = Elm.fullscreen(Elm.SlimeWarz, {rawServerInput: ""});
var socket = new WebSocket("ws://localhost:4567");
socket.onopen = function(){
console.log("Socket has been opened.");
}
socket.onmessage = function(msg){
game.ports.rawServerInput.send(msg.data);
}
game.ports.sendToServer.subscribe(sendOverWebsocket);
function sendOverWebsocket(str) {
socket.send(str);
}
Then in elm, I can send data using a ported Signal called sendtoServer
port sendToServer : Signal String
and I can view all the data I receive through the ported signal rawServerInput
port rawServerInput : Signal String
Answer
I'm going to use part of my answer to this question. I think your solution to use ports and do the websocket part in JavaScript is better than the hack I described in that answer, but you may still want to look at it. Once Elm 0.15 is released this problem should go away entirely because of a language feature and the revamp of Websocket (Http gets revamped too btw).
Context: Reason for error
The reason you get the runtime error is because of a compiler bug. The compiler only generates correct code on recursive functions, while it accepts any recursive value. Notice that your input depends on sendToServer, sendToserver depends on state and sContext: tate depends on input.
Context: Code architecture
Those kinds of cyclic signals are usually a sign of bad program architecture. You can find more on that subject here. But your architecture is not at fault here. The problem lies with the Websocket library which doesn't steer you in the right direction.

Configure Linux I2C Speed

I am using I2C on the Snowball board, running at 400KHz by default and would like to reduce this to 100KHz.
I use the api defined in and configure as follows
m_fd = open(m_filename.c_str(), O_RDWR);
if (ioctl(m_fd, I2C_SLAVE_FORCE, m_addr) < 0)
{
throw I2cError(DeviceConfigFail);
}
Does anyone know how I would go about changing the speed to standard mode.
Thanks
You can change the I2C SCL frequency in your driver's 'struct i2c_gpio_platform_data'.
static struct i2c_gpio_platform_data xyz_i2c_gpio_data = {
.sda_pin = GPIO_XYZ_SDA,
.scl_pin = GPIO_XYZ_SCL,
.udelay = 5, //#udelay: signal toggle delay. SCL frequency is (500 / udelay) kHz
....
};
Changing 'udelay' changes your 'xyz' i2c device's clock frequency.
You should change the I2C Frequency in driver source file of the corresponding peripheral (ie: Slave device to which you are communicating through I2C. Example: EEPROM/Camera etc.)
You may find some macro defined in that driver source code... like:
#define EEPROM_I2C_FREQ 400000 //400KHz
Change it to:
#define EEPROM_I2C_FREQ 100000 //100KHz
Only for that corresponding driver, I2C frequency/speed will be changed.

Resources