I have a question concerning the addresses of the interrupt vectors in ATMega2560.
According to the data sheet, the vectors are at the program addresse $0000, $0002, $0004, ..., $0070.
After disassembling code of an ATMega2560 (on an Arduino Mega board) I noticed that the vector are at the addresses $0000, $0004, $0008, ..., $00E0.
I assume that (2) is correct. According to the AVR Instruction set manual a jmp instruction has a 4 Byte opcode which fits this assumption (and the assembler uses the jmp instruction to jump to the ISR).
But why does the data sheet then tell something different? Or is my understanding maybe totally wrong?
Thanks a lot for all answers and kind regards!
Related
I am working ESP-idf to program my ESP32 board. My Goal is to make it scan for a specific BLE (Bluetooth Low Energy) Device.
I figured out how to make it scan by using one of the examples that are provided by "Espressif" called "ibeacon_demo.c"
the thing is I don't know how to extract the address of any searched device and have it as string so I can compare it with the my BLE device address.
ibeacon_demo.c:
https://github.com/pycom/pycom-esp-idf/blob/master/examples/bluetooth/ble_ibeacon/main/ibeacon_demo.c
I am pretty sure there is something has to be done in this statement:
if (esp_ble_is_ibeacon_packet(scan_result->scan_rst.ble_adv, scan_result->scan_rst.adv_data_len)){
esp_ble_ibeacon_t *ibeacon_data = (esp_ble_ibeacon_t*)(scan_result->scan_rst.ble_adv);
ESP_LOGI(DEMO_TAG, "----------iBeacon Found----------");
esp_log_buffer_hex("IBEACON_DEMO: Device address:", scan_result->scan_rst.bda, BD_ADDR_LEN );
esp_log_buffer_hex("IBEACON_DEMO: Proximity UUID:", ibeacon_data->ibeacon_vendor.proximity_uuid, ESP_UUID_LEN_128);
uint16_t major = ENDIAN_CHANGE_U16(ibeacon_data->ibeacon_vendor.major);
uint16_t minor = ENDIAN_CHANGE_U16(ibeacon_data->ibeacon_vendor.minor);
ESP_LOGI(DEMO_TAG, "Major: 0x%04x (%d)", major, major);
ESP_LOGI(DEMO_TAG, "Minor: 0x%04x (%d)", minor, minor);
ESP_LOGI(DEMO_TAG, "Measured power (RSSI at a 1m distance):%d dbm", ibeacon_data->ibeacon_vendor.measured_power);
ESP_LOGI(DEMO_TAG, "RSSI of packet:%d dbm", scan_result->scan_rst.rssi);
}
here is the API reference for the example I used "ibeacon_demo.c"
[https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/bluetooth/esp_gap_ble.html#_CPPv428esp_ble_gap_update_whitelistb13esp_bd_addr_t22esp_ble_wl_addr_type_t][1]
You question is 2 parts, how to extract the address and how to compare it to the one your looking for.
The first is already answered for you, as this sample is extracting the address and putting it in the log:
esp_log_buffer_hex("IBEACON_DEMO: Device address:", scan_result->scan_rst.bda, BD_ADDR_LEN );
But your second question take a deeper understanding of how to compare byte arrays. I can try to help you understand the second part by telling you that the address is a byte array and that it is 6 bytes long, that's what the BD_ADDR_LEN constant is telling you.
Now you must compare the 2 byte arrays.
After you figure that out you can get into public and random addresses. But for now that's enough.
I recently got hold of a ZX Spectrum +3 and am trying to get RS232 working with the spectrum. I’ve built a cable (‘BT’ style connector <-> DB9 serial) following the pin out of the cable (Spectrum 128 RS232 data cable) here.
The other end of the cable is connected to the PC using a USB-Serial adapter. I'm using Moserial on Linux to communicate with the Spectrum.
The cable works and I can use LLIST to print BASIC programs over the serial port, but I'm unable to get the Spectrum to read from the serial port reliably - even when enabling hardware handshaking (DTR/CTS) in Moserial.
I wrote a simple program in +3 BASIC to print received characters to the screen. It seems the first character is received OK, but the remaining characters are dropped or become corrupted.
Here is an example of what the Spectrum outputs when attempting to send 'zx spectrum' at 300 baud:
z[dot/box character]. VAL$ [box character]MOVE VAL$ VAL$ ?)
(it seems VAL$ and MOVE$ are each a single character in the Spectrum's ROM)
screenshot:
And the BASIC program which opens the serial port, and prints received characters to the screen:
10 FORMAT LINE 300
20 FORMAT LPRINT "r"
30 FORMAT LPRINT "e"
40 OPEN #4,"p"
50 PRINT INKEY$#4;
60 GO TO 50
I discovered that if I send characters one-by-one from the PC with a long enough delay between them, I can get a much more reliable output from the Spectrum. I tested this with different delays, and 80ms worked the best. I don't really want to use this approach as a solution - it's awfully slow and occasionally some characters are dropped.
Could this be an issue with the Spectrum itself? Or am I missing something in my setup? Something just doesn't seem right, I know there is a program loader for the spectrum over serial - so surely the spectrum must be able to accept serial input without a 80ms delay per character?
The ZX Spectrum Interface 1 works by bit-sampling, in a software loop, with delays, so that it can look for the start bit and then look for the other bits. There is no shift register. It's all done in software.They don't even use interrupts or some other kind of fixed external timer to generate baud rate delays.
As a result, it doesn't even start looking for a start bit until it knows you're looking for input... Now that you have an idea what's going on I'm pretty sure you've already seen the problem there? If you're sending data too fast, then your basic program doesn't even have time to go back to the receive routine to look for start bits, and start bits are going to be lost, or more likely, you're going to pick up a bit transition mid-byte and receive gibberish... So you need to make sure that there's a delay between bytes and your Spectrum is ready to receive the next byte before you start transmitting.
Hope this helps even though it's a while ago, but others will find this so...
In zx spectrum 48k, with interface 1, i must choose how the rs232 will work.
Mode t : text ->rx and tx only character in 7bit
Mode b: byte -> rx and tx full byte (8 bit)
Maybe you must chek that.
On 48k with interface 1
FORMAT "b";9600
Then , the spectrum works in 8bit data at 9600 bauds.
In your code, i dont see how will works.
My best regards.
I came across your problem as I was trying to do the same!
You need to enable RTS/CTS handshaking in your linux (PC) application, not DTR/RTS.
This works for me on my Spectrum+2:
100 REM ** Receive Test **
110 REM ** Use RTS/CTS **
120 CLS
130 FORMAT "p";9600
140 OPEN #4,"p"
150 PRINT INKEY$#4;
160 GO TO 150
There's software incompatibility between modern computers and ZX Spectrum when doing serial communication. It can be fixed, but not from Basic. The problem with RTS/CTS is that after Spectrum signals that it can't receive any more data via the CTS signal: modern UART chips will assume that the receiving computer is still able to receive cca. one buffer of data (=up to 32 bytes). But ZX Spectrum only has 1 byte buffer. So when Spectrum says its' full, it will get flooded by additional 32 bytes of data.
That is the reason anything faster then 1200 bauds will not work from BASIC. However ... I got ZX Spectrum to run reliably at 57600 and with error correction at 115200. By simply expecting up to 32 bytes after I signal the PC to stop sending data.
I've had all this working years ago with my Spectrum and the ZX Interface 1's own rs232 port, but I wrote some C program using an old Windows 386 computer.
I still have the hardware and the cables. In fact, now that I remember I had to build my own "null modem" cable and connect it from the RS232 port on the computer to the ZX Interface 1 (I have an old Sony Vaio laptop with an RS232 port).
I was even able to download TAP files to play on the real spectrum. I'll dig up what I have and get back to you.
I was working on this project : http://elm-chan.org/works/sd8p/report.html
and I failed in every possible way from the start. Now that the .Hex files have been uploaded, and the fuses written, when I plugged the SD card in, nothing happened. Nothing at all. Directly asking for a solution might be impossible here as I have no idea what went wrong. So instead I tested the speaker's positive connection with the arduino serial plotter, and I found some interesting results. The output gave some cool irregular pattern of waves,similar to what I would expect from a sound output. But there was no sound, and I suspect that it was because of the output size being too small.(60/1023 is around 0.06 volts, 200/1023 is around 0.2 volts and the bigger output at 500++ levels out, so it shouldn't produce a sound.)
So now I would like to ask whether I can change the fuses of the .hex file(or the hex file itself, but its big.) to produce a larger output. I have not much understanding in hex files or even AVR devices, so any hep at all would be useful.
Thanks in advance.
the graphs
Please let me know if any other information is needed.
Your voltage output on a GPIO pin is limited to your supply voltage, so no you probably can't fix your problem by changing the software or the fuse bits. Depending on your current supply voltage, you might be able to crank that higher, which would increase your voltage output of the PWM, but the supply voltage can only go so high without damaging the chip.
That being said, you need to disconnect the amp and speaker from the AVR and probe the output pin of the PWM and make sure that it is actually producing a signal on that pin. The plots that you posted with that amplitude look like they are nothing but random electrical noise to me.
Hi i am working on Tmote sky motes (MSP430 microprocessor) with contiki os. I want to know the number of instruction cycles used when I do a multiplication operation in my programming (software).
Thank you,
Avijit
The msp430 is a 16-bit system, so 32-bit values are not supported directly. A 32-bit operation is typically translated to assembly code as a sequence of 16-bit ops.
The execution times of 8-bit and 16-bit operations can be found in TI application report "The MSP430Hardware Multiplier":
Table 4. CPU Cycles Needed With Different Multiplication Modes
OPERATION: Unsigned Multiply (MPY)
SOFTWARE LOOP: 139...171
HARDWARE MPYer: 8
SPEED INCREASE: 17.4...21.4
OPERATION: Unsigned multiply-and-accumulate (MAC)
SOFTWARE LOOP: 137...169
HARDWARE MPYer: 8
SPEED INCREASE: 17.1...21.1
OPERATION: Signed Multiply (MPYS)
SOFTWARE LOOP: 145...179
HARDWARE MPYer: 8
SPEED INCREASE: 18.1...22.4
OPERATION: Signed multiply-and-accumulate (MAC)
SOFTWARE LOOP: 143...177
HARDWARE MPYer: 17
SPEED INCREASE: 8.4...10.4
The HW multiplier should be active with default compilation settings, but check the generated object file with msp430-objdump to make sure.
You can use naken_asm by Michael Kohn to disaemble an Intel hex or ELF file and it will calculate the cycle counts for each instruction. I've used it in the past and the cycle counter is OK for CPU (such as in your Tmote) but not fully supported in CPUX.
You can invoke it from the command line as simply as:
naken_util -disasm <infile>
where <infile> is the name of your hex or ELF file. The default processor is MSP430, but you'd need the assembly listing from your compiler in order to be able to match up the original code with the disassembled code which includes cycle counts.
Another alternative would be to use MSPDebug's tracer option which can track running software and provide an up-to-date instruction cycle count. However, I've never used it for that purpose so cannot provide an example.
I am trying to boot my small ARMv7 kernel (which runs just fine using qemu vexpress model) in ARMv8 Foundation Model v2.1. The model boots at level EL3 / 64 bits, and I managed to go down to level EL1 / 32 bits, but I encounter some issues (in a few words, the timer doesn't tick and some kprintf are missing, but that's not the issue here).
To debug my UART issue, I wanted to use the led / switches provides by the model. I can read their value from software quite easily, but I can't write a new value to either of them. The kernel seems to hang. Here is a minimal asm code that writes to the switches register:
.global Start
Start:
# we are in EL3 / 64 bits mode
# create the 0x1C010000 + 0x4 address of switches
mov x0, #4
movk x0, #0x1c01, lsl #16
# value to write
mov w1, #0xaa
# actual writing
strb w1, [x0]
It seems I am stuck at the strb instruction. For the record, if I replace strb with ldrb, I can correctly read and display the value of this register (I played with the --switches flag to be sure it worked).
Any one knows what I am doing wrong here ?
EDIT: thanks to unixsmurf suggestions, I know now that I got an synchronous Data Abort Exception with no level change, and that the reason is "Synchronous External Abort". I don't know how to inspect further, I guess I'll try ARM's forum.
Best,
V.
The ARM community finally solved the problem. The complete discussion can be found here.