I'm working on a firmware updater, so that the main controller in the system can program the other STM32 chips. I'm using UART at 115200 bps with 8E1 as written in the app notes AN2606 and AN3155. Currently I'm trying to flash an STM32F429. I can read the flash without problems.
To test the writing functionality I'm writing 8 bytes to addresses which are multiples of 4 as suggested in AN3155.
I've checked the data lines with a logic analyzer, and everything is sent correctly and the STM responds ACK to everything.
When I try to read it back, I get random values at those locations. The values are always the same when writing to the same base address, but they change when writing elsewhere.
I've set the Voltage Range Configuration Register (AN2606 page 30) to 0x03, because my power supply is 3.3V. The explanation of this register is pretty confusing, so I'm not even sure if this setting is right and I couldn't find anything else that could go wrong.
UPDATE:
I have tried to write to all 4-byte aligned addresses, and then read it back for comparison. I did this with various data sizes. All writes are incorrect to the base address of a sector. The failed addresses have these patterns:
Bytes Incorrect write addresses
4 0, 10, 20, 30, ...
8 0, 0C, 1C, 2C, 3C, ...
12 0, 08, 18, 28, 38, ...
16 0, 04, 14, 24, 34, ...
32 0 04, 14, 24, 34, ...
64 0, 04, 08, 0C, 14, 18, 1C, 24, ...
128 all
256 all
SOLUTION:
Doh! There was an issue with flash erasing that I haven't noticed.
Original STM bootloader is not good in the real development as it does not provide two essential functions.
it does not provide any decryption and your firmware can be stolen by anyone (so protecting the device does not make any sense as you have to publish "plain" not encrypted binary image)
it does not check the integrity of the application in the flash
it does not work with the protected devices
The easiest way is to write your own bootloader and implement all those functions.
Related
Hi I'm writing a kernel and plan to use MSI interrupt for PCI devices.
However, I'm also quite confused by the documentations.
My understanding about MSI are as follow:
From PCI device point of view:
Documentations indicate that I
need to find Capabillty ID = 0x05 to locate 3 registers: Message control (MCR), Message Address (MAR) and Message Data (MDR) registers
MCR provide control functionality for MSI interrupt,
MAR provide the physical address the PCI device
will write once interrupt occurs
MDR forms out the actual data it will write into the physical address
From CPU point of view:
Documentation shows that Message Address register contains fixed top of 0xFEE, and following by destination ID (LAPIC ID) and other controlling bits as follow:
The Message Data register will contain the following information, including the interrupt vector:
After reading all of these, I am thinking if the APIC_ID is 0x0h would the Message Address conflict with the Local APIC memory mapping? Although the address of FEE00000~FEE00010 are reserved.
In addition, is it true that the vector number in MDR is corresponding to the IDT vector number. In other words, if I put MAR = 0xFEE0000C (Destination ID = 0, Using logical APIC ID) and MDR = 0x0032 (edge trigger, Vector = 50) and enable the MSI interrupt, then once the device issues an interrupt CPU would correspondingly run the function pointed by IDT[50]? After that I write 0h to EOI register to end it?
Finally, according to the documentation, the upper 32 bit of MAR is not used? Can anyone help on this?
Thanks a lot!
Your understanding of how to detect and program MSI in a PCI (or PCIe) device is correct.*
The message address controls the destination (which CPU the interrupt is sent to), while the message data contains the vector number. For normal interrupts, all bits of the message data should be 0 except for the low 8 bits, which contain the vector.
The vector is an index into the IDT, so if the message data is 0x0032, the interrupt is delivered through entry 50 of the IDT.**
If the Destination ID in an interrupt message is 0, the Message Address of the MSI does match the default address of the local APIC, but they do not conflict, because the APIC can only be written by the CPU and MSIs can only be written by devices.
On x86 platforms, the upper 32 bits of the message address must be 0. This can be done by setting the upper part of the message address to 0 or by programming the device to use a 32-bit message address (in which case the upper message address register is not used). The PCI spec was designed to work with systems where 64-bit MSI addresses are used, but x86 systems never use the upper 32 bits of the message address.
Reprogramming the APIC base address by writing to the APIC_BASE MSR does not affect the address range used for MSI; it is always 0xFEExxxxx.
* You should also look at the MSI-X capability, because some devices support MSI-X but not MSI. MSI-X is a bit more flexible, which inevitably makes it a bit more complicated.
** When using the MSI capability, the message data isn't exactly the value in the Message Data Register (MDR). The MSI capability allows the device to use several contiguous vectors. When the device sends an interrupt message, it replaces the low bits of the MDR with a different value depending on the interrupt cause within the device.
I have a ADRF6720-27 EVAL Board. It connects to the host PC using CY7C68013a; the board also has a 64Kb EEPROM 24LC641; ADRF6720-27 is a RF modulator which is programmed via its SPI pins connected to pins 33, 34 and 35 of CY7C68013a.
The evaluation software runs fine. What I want to do is to load a program into the EEPROM (24LC641) such that the board generates stepped frequency from 700MHz to 2GHz.
I suppose this can be achieved if the program drives the three GPIO pins (say 33, 34, 35 in CY7C68013a) to drive the SPI slave (ADRF 6720-27) using bit-banging.
Installing the FX2LP-USB software detects the board correctly. My question is: in the IDE Keil uVision, which header files do I include while writing the program? There are many files in a demo project like bulkloop.c, which ones do I modify and which ones should be left as it is for my own purpose mentioned in the 1st and 2nd paragraph?
Thanks
I have a custom circuit with STM32F030F4P6 as a main controller and HDY-08 flashed with HM-10 firmware as a Bluetooth LE transmitter.
What I wanted to do on circuit power on is to manually set the module up with custom parameters (name, baud, mode) and then proceed to the main calculating part.
However, what I noticed is that module won't act after any of the AT commands received, though it responds with OK+... strings.
For example, I send "AT+NAMEmyname" and receive "OK+Set:myname", however, the name doesn't change at all and remains HMSoft in Bluetooth scan on my phone.
Being on baudrate of 9600 I send "AT+BAUD4" and receive "OK+Set:4", then I send "AT+BAUD?" STILL on the baud of 9600 and receive the same: "OK+BAUD4" - the module keeps working on 9600, however, says it is on 115200. Tried playing with pulling reset and sys_key up and down for different time intervals, which results in nothing but not working AT commands.
Currently I have my module with RESET pin pulled up and SYS_KEY pulled up for 1200 milliseconds at start, then it is pulled down and then I proceed to send AT commands with delays of 250 milliseconds between Transmitting/Receiving sessions:
HAL_GPIO_WritePin(SYSTEM_KEY_GPIO_Port, SYSTEM_KEY_Pin, 1);
HAL_Delay(1200);
HAL_GPIO_WritePin(SYSTEM_KEY_GPIO_Port, SYSTEM_KEY_Pin, 0);
HAL_UART_Transmit(&huart1, (uint8_t*)setup, 8, 100);
HAL_UART_Receive(&huart1, (uint8_t*)response, 8, 100);
HAL_Delay(250);
HAL_UART_Transmit(&huart1, (uint8_t*)reset, 8, 100);
HAL_UART_Receive(&huart1, (uint8_t*)response2, 8, 100);
HAL_Delay(250);
HAL_UART_Transmit(&huart1, (uint8_t*)check, 8, 100);
HAL_UART_Receive(&huart1, (uint8_t*)response3, 8, 100);
The problem was solved:
I don't know why, but after several times of dragging the same code here and there, I got the working solution:
RESET Pin 1
SYSTEM_KEY Pin 1
PWR 1
SYSTEM_KEY Pin 0
Delay 1200 millis
SYSTEM_KEY Pin 1
AT+BAUD4 -> OK+Set:4
Delay 250 millis
Reinitialize UART on STM, now with baudrate of 115200
AT+BAUD? -> OK+Get:4
It works, data flows as needed.
Thank you me for answering <3
I have recorded a script in LR11.5 version using Winsocket protocol (Only protocol I was able to use to record my application). I want to correlate few receive buffers. In one such buffer I have two values to correlate, given that both are same values. Buffer is as below :-
recv buf30 136
"&SOT&148\vF.USER\vSK1\vTIME.OUT.MINUTES&EOT&&START&148\v3\v999&END&&START&"
"99\v56\v28 FEB 2016\vSK1\v8298,\v28 FEB 2016 16:23\vg15.0.00\vr11.000&END&"
The high lightened values are the one that I need to correlate. What should I do for this. I have used to lrs_save_param() function for correlation.
The correlation API you need depends on the network protocol recorded in your script. If it uses constant offsets of fields, you can safely use lrs_save_param. The result of correlation would be something like this:
lrs_save_param("socket0", LRS_LAST_RECEIVED, "param1", 16, 3);
lrs_save_param("socket0", LRS_LAST_RECEIVED, "param2", 138, 3);
(Zero-based offset, length of the value.)
But if the offsets vary from run to run, the situation is more complicated: you'll have to specify boundaries for the extracted values. For instance:
lrs_save_searched_string("socket0", LRS_LAST_RECEIVED, "param1", "LB/BIN=\v", "RB/BIN=\v",
2, 0, -1);
lrs_save_searched_string("socket0", LRS_LAST_RECEIVED, "param2", "LB/BIN=\v", "RB/BIN=\v",
8, 0, -1);
(Left and right boundary, 1-based number of occurrence, offset from the left boundary, length, which is autodetected in this case.)
Please check the official documentation for details.
I'm working on an embedded system that currently only supports SDSC v1 cards. As it's getting harder and harder to find cards less than 2 GB, I'm trying to add support for SDHC cards. The communication with the card is done via the SPI bus.
So here is what I'm doing to initialise the card:
Send CMD0. Card returns 0x1
Send CMD8 + 0x1AA. Card returns 0x1 and 0x1AA
Send ACMD41. Card returns 0x0.
Afterwards, I read the MBR and figured out that there is a FAT16 partition at 0x30 LBA. However, reading a sector from that address (0x30*512) returns a repetition of 0x01 0x09...
When sending ACMD41, I'm sending command id 0x69. Is it correct? Or should I send CMD55 and then CMD1?
A diagram 1 shows that I need to send CMD58 and possibly CMD16 after sending ACMD41. Is it necessary? I was able to read a valid MBR without doing them.
1. http://elm-chan.org/docs/mmc/mmc_e.html
"ACMD" commands all require a CMD55 followed by the relevant command.
For example, for command ACMD41:
SD_command(55, 0, 0, 0, 0, 0xFF);
n= SD_command(41, SD2<<6 , 0, 0, 0, 0xFF);
Don't forget to OR in 0b01000000 to the first argument. The actual command isn't 55, it's 55|0b01000000 (0b01110111, decimal 119). I do it in the SD_command function itself.
Interfacing to SD cards is a HUUUUUGE pain, so don't give up. Good luck!