When I connect 8051 to an external memory, should I change the RD and WR signals in software or is this made by processor itself when I use the MOVX command?
For example I will read from some location at memory,
;CLR RD
MOV DPTR,#SOMELOCATION
MOVX A,#DPTR
is CLR read command required here or processor just clears that itself by looking if the code is
MOVX A,#DPTR ;or
MOVX #DPTR,A
If the processor has RD and WR lines, then yes, the processor will pulse the write line with timing as described in the data sheet as it executes the "movx #dptr,A" instruction. In addition, ALE would have been pulsed to latch the low byte of the address for the memory.
If for some reason it was necessary to operate the chip write using a clear bit instruction as you state above, you are doing it in the wrong place. You would need to set up address and data THEN pulse write low, then return it high, before any other change in address and data.
Related
What part of the computer program fetches the relevant data from memory?
For example:
let arr = [1,2,3,4]
let x = arr[3]
What is responsible for fetching the data stored at the address ((the address of array arr) + 3), I know a pointer points to the memory address of interest, but that's an abstraction of what's happening, what's really responsible for fetching the stored data in memory, and storing it in a register for an operation, or in a different memory address?
The processor has an address generator, and a read & write interface. This is true across all processors but the details vary.
Simple, educational and older processors have an MAR, memory address register, and MBR, memory buffer register, and some control signals. That constitutes the cpu to memory interface.
To write to memory, the CPU puts a value into the MBR and MAR, and then asserts a write control signal. The memory responds by performing the requested write operation (and may signal the processor that it is done).
To do a read operation, the CPU puts a value into the MAR, and asserts a read control signal; the memory responds puttiing a value into the MBR, (and asserts a ready control signal). The processor takes the value from the MBR and transfers it to where it should go.
You might look up architectures like LC-3, MARIE, and look for block diagrams having those specific registers. Modern processors introduce caches in between the CPU and memory, so there are multiple memory interfaces.
The machine code program will use available instruction encodings to tell the processor when and what to read or write. The compiler's job is to identify machine code instruction sequences that will accomplish the C program's intent.
I have a ZTurn board that mounts a Zynq 7020. In the PL part I have a programmed code in AXI4-Lite slave that contains the programming code of the part of interest that I need (VHDL).
In this block, when I send "start" in the PS I write '1' to slv_reg0(0) and I tell it to start capturing data; it would be capturing 32-bit data (1 every 2 MHz) that I want it to store in DDR memory from the PL part.
At the end of the capture process, when I send "stop" in the PS (writting '0' in slv_reg0(0)), what I want is to stop saving data in DDR memory and then begin the process of reading the data from the entire written memory in the main.c file
I know that to do this I need to implement some kind of DMA connection but I would like to know how to do it. My level of knowledge in this field is very limited and I can't find any tutorial that fits my exact needs.
What I want to know is what I have to change from my AXI4-Lite slave and where to put the VHDL code and how to write the data to the DMA block in different addess positions.
Thank you.
I'm working on a dual OS system with STM32F103, I have two separate program that programmed on different FLASH locations. if both of the programs are the same, the only way to know which of them running is just by its start vector address.
But How I Can Read The Current Program Start Vector Address in STM32 ???
After reading the comments, it sounds like what you have/want is a bootloader. If your goal here is to have two different applications, one to do your main processing and real time handling and the other to just program new firmware, then you want to make a bootloader in your default boot flash space.
Bootloaders fundamentally do a few things, everything else is extra.
Check itself using some type of data integrity check like a CRC.
Checks the application
Jumps to the application.
Bootloaders will also program applications in the app space and verify they are programmed correctly before jumping as well. Colin gave some good advice about appending a CRC to the hex file before it is programmed in flash space to verify the applications.
There are a few things to look out for. The first would be the linker script and this is extremely important. A linker script will be used to map input objects to output objects and then determine based upon that script, what memory space they go into. For both of your applications, you need to create a memory map of how you want both programs to sit inside of the flash space. From this point, you can then make linker scripts for both programs so that a hex file can be generated within the parameters of what you deem acceptable flash space for the program. Each project you have will have its own linker script. An example would look something like this:
LR_IROM1 0x08000000 0x00010000 { ; load region size_region
ER_IROM1 0x08000000 0x00010000 { ; load address = execution address
*.o (RESET, +First)
*(InRoot$$Sections)
.ANY (+RO)
}
RW_IRAM1 0x20000000 0x00018000 { ; RW data
.ANY (+RW +ZI)
}
}
This will give RAM for the application to use as well as a starting point for the application.
After that, you can start the bootloader and give it information about where the application space lies for jumping and programming. Once again this is all determined by you from your memory map and both applications' linker scripts. You are going to need to add a separate entry inside of the linker for your CRC and length for a comparison of the calculated versus stored as well. Whatever tool you use to append the CRC to the hex file and have it programmed to flash space, remember to note the location and make it known to the linker script so you can reference those addresses to check integrity later.
After you check everything and it is determined that it is okay to go to the application, you can use some ARM assembly to jump to the starting application address. Before jumping, make sure to disable all peripherals and interrupts that were enabled in the bootloader. As Colin mentioned, these will share RAM, so it is important you de-initialize all used, otherwise, you'll end up with a hard fault.
At this point, the program used another hex file laid out by a linker script, so it should begin executing as planned, as long as you have the correct vector table offset, which gets into your question fully.
As far as your question on the "Flash vector address", I think what your really mean is your interrupt vector table address. An interrupt vector table is a data structure in memory that maps interrupt requests to the addresses of interrupt handlers. This is where the PC register grabs the next available instruction address upon hardware interrupt triggers, for example. You can see this by keeping track of the ARM pipeline in a few lines of assembly code. Each entry of this table is a handler's address. This offset must be aligned with your application, otherwise you will never go into the main function and the program will sit in the application space, but have nothing to do since all handlers addresses are unknown. This is what the SCB->VTOR is for. It is a vector interrupt table offset address register. In this case, there are a few things you can do. Luckily, these are hard-coded inside of STM generated files inside of the file "system_stm32(xx)xx.c" (xx is your microcontroller variant). There is a define for something called VECT_TAB_OFFSET which is the offset in the memory map of the vector table and is assigned to the SCB->VTOR register with the value that is chosen. Your interrupt vector table will always lie at the starting address of your main application, so for the bootloader it can be 0x00, but for the application, it will be the subtraction of the starting address of the application space, and the first addressable flash address of the microcontroller.
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/******************************************************************************/
Make sure you understand what is expected from the micro side using STM documentation before programming things. Vector tables in this chip can only be in multiples of 0x200. But to answer your question, this address can be determined by a few things. Your memory map, and eventually, you will have a hard-coded reference to it as a define. You can figure it out from there.
Hope this helps and good luck to you on your application.
I worked with megafunctions to generate 32bit data memory in the fpga.but the output was addressed 32bit (4 bytes) at time , how to do 1 byte addressing ?
i have Altera Cyclone IV ep4ce6e22c8.
I'm designing a 32bit CPU in fpga ,
Nowadays every CPU address bus works in bytes. Thus to access your 32-bit wide memory you should NOT connect the LS 2 address bits. You can use the A[1:0] address bits to select a byte (or half word using A[1] only) from the memory when your read.
You still will need four byte write enable signals. This allows you to write word, half-words or bytes.
Have a look at existing CPU buses or existing connection standards like AHB or AXI.
Post edit:
but reading address 0001 , i get 0x05060708 but the desired value is 0x02030405.
What you are trying to do is read a word from a non-aligned address. There is no existing 32-bit wide memory that supports that. I suggest you have a look at how a 32-bit wide memory works.
The old Motorola 68020 architecture supported that. It requires a special memory controller which first reads the data from address 0 and then from address 4 and re-combines the data into a new 32-bit word.
With the cost of memory dropping and reducing CPU cycles becoming more important, no modern CPU supports that. They throw an exception: non-aligned memory access.
You have several choices:
Build a special memory controller which supports unaligned accesses.
Adjust your expectations.
I would go for the latter. In general it is based on the wrong idea how a memory works. As consolidation: You are not the first person on this website who thinks that is how you read words from memory.
I already read the datasheet and google but I still don't understand something.
In my case, I set PIN RC6 of a PIC18F26K20 in INPUT mode:
TRISCbits.TRISC6 = 1;
Then I read the value with PORT and LATCH and I have different value!
v1 = LATCbits.LATC6;
v2 = PORTCbits.RC6;
v1 gives me 0 where v2 gives 1.
Is it normal?
In which case we have to use PORT and in which case LATCH?
The latch is the output latch onto which values are written. The port is the voltage at the actual pin.
There are a few situations where they can be different. The one that I've encountered most frequently is if you have a pin (accidentally) shorted to ground. If you set the latch high, the latch will read high, but the port will read low because the voltage on the pin is still approximately ground.
Another situation leading to what you've described is when the port pin hasn't been configured correctly. I (and everyone I work with) have spent many hours trying to figure out why our PIC isn't working to expectations, to eventually find out that we glossed over turning off the analog modules, for instance. Make sure you go over the section I/O Ports -> PORT?, TRIS?, and LAT? registers in the datasheet. You can get more info in the Microchip wiki page which explains about reading the wrong value immediately after you write an output on a pin connected to a capacitive load.
That wiki page also explains:
A read of the port latch register returns the settings of the output drivers, whilst a read of the port register returns the logic levels seen on the pins.
Also, here's a snippet from the I/O Ports section on the 18F14K50 (which ought to be the same as the rest of the 18F series):
Each port has three registers for its
operation. These registers are:
TRIS register (data direction register)
PORT register (reads the levels on the pins of the device)
LAT register (output latch)
So in most situations, you will write to the latch and read from the port.
I'll adapt my answer from Electrical Engineering.
Let's use the picture from manual:
When you write a bit in a I/O pin, you're storing this bit from Data Bus to the Data Register (D-FlipFlop). If TRISx of this bit is 0, so data from Q of the Data Register will be in the I/O pin. Write in LATx or PORTx is the same. See below in red:
On the other hand, read from LATx is different of read from PORTx.
When you're reading from LATx, you're reading what is in the Data Register (D-FlipFlop). See picture below in green:
And when you read from PORTx, you're reading the actual I/O pin value. See below in blue:
PIC uses read-modify-write to write operations and this can be a problem, so they use this shadow register to avoid it.
Here's a useful summary from the datasheet.
11.2.3 LAT Registers
The LATx register associated with an I/O pin eliminates the problems that could occur with
read-modify-write instructions. A read of the LATx register returns the values held in the port
output latches, instead of the values on the I/O pins. A read-modify-write operation on the LAT
register, associated with an I/O port, avoids the possibility of writing the input pin values into the
port latches. A write to the LATx register has the same effect as a write to the PORTx register.
The differences between the PORT and LAT registers can be summarized as follows:
A write to the PORTx register
writes the data value to the port
latch.
A write to the LATx
register writes the data value to the
port latch.
A read of the PORTx
register reads the data value on the
I/O pin.
A read of the LATx
register reads the data value held in
the port latch.
Yes, it's normal to read PORTx and LATx and occasionally find they have different values.
When you want to read whether some external hardware is driving a pin high or low, you must set the pin to input mode (with TRIS or the DIR register), and you must read PORTx. That read tells you if the actual voltage at the pin is high or low.
When you want to drive a pin high or low, you must set the pin to output (with TRIS or the DIR register); you should write the bit to the LATx register.
(Writing that bit to the PORTx register may seem to do the right thing: that pin will -- eventually -- go high or low as commanded. But there are many cases -- such as when some other pin on that port is connected to an open-collector bus -- that writing to one bit of the the PORTx register will mess up the state of the other pins on that port, leading to difficult-to-debug problems).
Open Circuits: read before write
My recommendation is to regard the PORT values as read-only. The LAT values may be read or written, but the value read will be the last value written, not the input value of the pin.
On older PICs, the LATx values didn't exist; the only way to write to a port was via the PORTx registers. Curiously, some of the really old PICs, back from the General Instruments (pre-Microchip) days, supported LATx, but Microchip didn't add that feature until the PIC18x line.
A write to the PORTx register writes the data value to the port latch.
A write to the LATx register writes the data value to the port latch.
A read of the PORTx register reads the data value on the I/O pin.
A read of the LATx register reads the data value on the port latch.
Use LATx: to write to an output pin
Use PORTx: to read an input pin
For all PICs with LATx registers, all INPUT must be from PORTx and all OUTPUT should be to LATx, which totally avoids the problem of flipping bits when you write to a single bit of the port.
I recently experienced that writing on PORTx Ri (e.g. PORTC RC1) of PIC18F14K50 is ineffective when another PORTx Rj (e.g. PORTC RC0) was already set.
I observed a peek in the oscilloscope on PORTx Ri but I was unable to sustain the output.
This issue has vanished as soon as I was writing on LATx.
LATx writing looks mandatory on PIC18 and PORTx writing prohibited.
It is always recommended to write to LAT, read from PORT, the reason is when the port is used as output, bit operation of PORT will do read modify write instruction.
Read modify write Instruction have some pitfalls, based on the output capacitance (rise time of the port pins) which may set the port pins to wrong value, when two consecutive READ modify WRITE instruction is executed.
So always write to LAT and read from PORT (input pins)