c++ code optimization breaks SPI on STM32 - stm32

I am using STM32F103VET6 with Keil v5.36 (armclang v6.16, c11, c++11) and trying to flash TI LMX2820 PLL.
SPI speed is 125 Kbits/s
I try the same code with -O0 optimization and with -O1, LTO, -O3+LTO,
-Oz Image size, -Oz Image size + LTO
Any of this optimization(except -O0, ofc) breaks PLL program operation. Using logic analyzer I found that without optimization it sends the same 375 byte array for nearly the same time (0.04929s without optimization and 0.04729s with). Data seems to be similar.
But with code being optimized, program operation failes (synth don't lock) about 9 times from 10, though sending the same data.
Also I've found that with code optimized, if I touch SDI (MOSI) pin with oscilloscope, program performs ok...

Related

STM32 bootloader failure to erase

I am writing an external bootloader for the STM32F730Z8 - (why? I need one windows code that can run the bootloader for the STM32, or use the STM32 to reprog a connected ATF1508 for my client). I've done this before, using info in AN3155 and AN2606. On lesser CPUs, this has had no difficulty (i.e. STM32L4P5). In this case, I try the same:
1-cycle \RESET & BOOT0 to boot to supervisor mode
2-autobaud successfully
3-send 0x00 to get the list of commands, successfully
4-send 01 to get the version and protection, successfully (vers 49, rp and nt both 0)
5-send 02 to get chip id (0x0452), successfully
6-send 0x73 to write-unprotect flash, successfully (i.e. receive back two ACK)
7-send 0x44 to begin an extended erase (intending only to erase sector 0).
This is where it fails. I get neither ACK nor NACK - it just times out. I don't even get to the second half of the extended-erase command where I send it the sector info. (On the STM32L4P5 it succeeds here easily and goes on to finish erasing, then to write code successfully.)
I've tried very long waits & repeat loops to wait for the ACK (many minutes). From past experience this should be fast, it is only the second stage where I tell it how much flash to erase that takes any significant time.
I've inspected the protection option areas of memory, at 0x1FFF0010, 0018, and they are unprotected, as per factory defaults.
I'm communicating over an FT231XS-R, using the D2XX driver calls. I can mess with the baud rates and such, but that only prevents it from autobauding...and we're doing that fine (9600/8/1/E). I've played with the D2XX SetTimeouts - if set too hasty that only screws up earlier commands. I'm wired to a 20 MHz crystal, and the application runs at 200 MHz, but my understanding is that the bootloader just runs at the internal RC clock rate.
I'm certainly missing something stupid, but I didn't see it in the documentation. Help?
Jeff Casey / Rockfield Research Inc. / Las Vegas, NV
Fixed, disregard.
The fineprint of AN3155 clued me in. On the description of the Write Unprotect command, it says that a system reset will be performed after completion. How did I miss this on the STM32L4P5? I just didn't read it. But why did it work then? In the really fine print next page, in a footnote to the flowchart, it says that they were just foolin'....system reset is only called for some (..list omitted..) and for other STM32 products no system reset is called for.
My earlier success had the following sequence:
reboot-supervisor
autobaud
get
gvrp
gid
wpun
xerase
wpun
write
verify
reboot-user
obviously that doesn't work for the F730. what works is:
reboot-super
autobaud
get
gvrp
gid
wpun
reboot-super
autobaud
get gvrp
gid
xerase
reboot-super
autobaud
get
gvrp
gid
write
verify
reboot-user
(obviously I can skip a few of the repeated steps, like get-id, but basically it needed a reboot and re-autobaud.)
note that i had to reboot-super a 3rd time...this was because the write attempt timed out after the xerase unless i went through the whole sequence again. funny, though, the spec doesn't say anything about resetting after an erase. i cross posted this question on the STM32 community site, and I'll do the same with this answer and ping them on this.
Thanks for reading, cheers. Jeff

Rasberry Pi Data Collection (First Steps)

I work in industrial automation and the functions of automation processors and software are locked down. I'm trying to sample and collect an analog signal at as fast of a rate as I can, <=10ms.
I have tried VB into excel, using a DDERequest and incrementing a delayed loop.
Application.Wait is too slow (1s)
"Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)," had the most promise, but too slow (100ms). It can be pushed faster, but this is on my computer, and then grabbing the float from the automation processor over ethernet... 100ms is the fastest without distorting the "real-time sample."
I have tried a Python module that pulls the float from the IP traffic. (Still over ethernet and too slow)
#x parameters
sample = .001
iterations = 1000
#Collection
for i in range(iterations):
# read the GPIO
float1 = SomeGPIOCommand(pin#)
float2 = SomeGPIOCommand(pin#)
# add the result to our ypoints list
ypoints1.append(float(float1.Value))
ypoints2.append(float(float2.Value))
#x
t = i*sample
xpoints.append(float(t))
# pause
time.sleep(sample)
#Plot
plt.plot(xpoints, ypoints1, 'c-', label='target' ) plt.plot(xpoints, ypoints2 ,'r--', label='actual')
OR is this fast of a sample rate going to require code under an IDE? The key here is matching the time stamp, in ms, exactly with the measured value.
I'd like to get there without an IDE, I just have no clue where to start, especially with the pi.
I have yet to see any example with this performance level.
Appreciate any help!
OR is this fast of a sample rate going to require code under an IDE?
No. A fast sample rate doesn't require coding under an IDE. Whether or not the code is developed under an IDE will have no bearing on sample rate.

HAL_SPI_Transmit works faster than direct registers manipulation, how come?

So knowing the fact that HAL is considered "slow" I decided to rewrtite a small routine in my programm using direct register access. And I decided to see, what I have won. Surprisingly, I actually lost.
So the code is
this->chip_select();
HAL_SPI_Transmit(hspi, spi_array, 3, HAL_MAX_DELAY);
this->chip_deselect();
this->chip_select();
SPI1->DR = spi_array[0];
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = spi_array[1];
while (!(SPI1->SR & SPI_SR_TXE));
SPI1->DR = spi_array[2];
while(SPI1->SR & SPI_SR_BSY);
this->chip_deselect();
So first I send 3 bytes using HAL, and then the same 3 bytes using the registers and same SPI.
Using HAL, the "interbyte" pause is 0,848ms.
And using registers - 1.192ms
How come? Isn't doing things with registers supposed to be quicker?
P.S. The stm32 is l071, 32 Mhz, SPI is 16Mhz.
Ok, so my mistake is - this was done on Debug build with 0 optimisation. With optimisation the register method is faster. Question is how to see the assembly code in Eclipse.

Raspberry Pi 7 Inch Touchscreen Brightness Control - How to avoid write operation to SD card

I'm just creating an app(kivy) for a raspberry pi(3b) with 7 inch touchdisplay. In addition I implemented a light sensor (TSL2591), which can regulate the brightness of the backlight using following command:
os.system('sudo sh -c "echo '+str(brightness)+' > /sys/class/backlight/rpi_backlight/brightness"')
with values of brightness 0 to 255
Works fine so far, but I do update the brightness once a second. If I'm not wrong, the command overwrites a config file and I mind of write access to the SD Card that often. I think the SD card will be corrupt after a short period of time.
For sure I can try to get less write operations, but it also leads to less smoothness:
update slower than 1 sec
only write if brightness value really changes
don't use all of the 255 steps
So the main question is: is there any other way to control the brightness? Or any workaround? I could not find a "real" Datasheet or any other advice on the internet. So maybe there is another way.
That's not a conventional disk file; it's a "device special file" which the kernel artificially creates to look like a disk file. It allows you to "talk" to device drivers using standard read() and write() calls.
You need not worry about SD card wear.

Can't receive from USB bulk endpoint despite Windows enumerates and libusb reads descriptor of STM32 custom device class

For a fast ADC sampling USB device, I am using the USB 2.0 High Speed capable STM32F733 with the embedded USB-HS PHY. In USBView, I can see that the device is enumerated, the libusb code opens the device and claims interface, but when I try to receive data with libusb_bulk_transfer, the operation times out (return code -12). Things I have tried: I have confirmed than when I request data with libusb_bulk_transfer, the device is interrupted. Note: I have DMA enabled in my class configuration C file and it is not clear to me how that is triggered. I have verified that the transfersize and packet count registers are being set correctly by the LL library function, and that when I request data from
Any tips on debugging such problems will be much appreciated - this board is my undergrad thesis due in under two months!
Desktop sequence:
libusb_get_device_list, libusb_get_device_descriptor, libusb_open, libusb_get_string_descriptor_ascii, libusb_free_device_list, libusb_bulk_transfer(devh, fat_EPIN_ADDR, inframe, fat_EPIN_SIZE, &gotBytes, 100). Where gotBytes is integer, and inframe is a large array.
Device firmware:
MX_USB_DEVICE_Init();
uint8_t txBuffer[10*fat_EPIN_SIZE];
while (1)
{
USBD_LL_Transmit(&hUsbDeviceHS, Custom_fat_EPIN_ADDR, txBuffer, Custom_fat_EPIN_SIZE);
HAL_Delay(1);
}
Custom_fat_EPIN_SIZE is 0x200 and the endpoint address is 0x81 (EP IN 1)
Installed driver for device is WinUSB (verified in Device Manger to be winusb.sys), and I am linking libusb-1.0 into my desktop program. You can find my source code at https://gitlab.com/tywonemi-school-stuff/silicon-radar-fun, the firmware is My SW/v1 and the desktop software is a Qt Creator project in My SW/Viewer, of note is usb.cpp. You can also compare with testing project/HIDTest, which is code that I tested with STM32F303 nucleo dev board where I was able to read an array through IN bulk endpoint with the Viewer application. However, F3 has the USB peripheral, while F7 has OTG_USB, and I am now attempting USB 2.0 compliant HS so there may be more protocol-based pitfalls. You can also find the output of the device descriptor etc from USBView in my SW/USBView_broken.txt
EDIT 1: I have found finally some concrete error in the STM32 behavior. The DMAADDR is set for EPIN 0x81, and never increments, despite the DMA being enabled. I have went through literally every occurrence of the word "DMA" in the USB_OTG periphery.
I thought it might be that my linker script makes my array be stored in DTCM or similar, and the OTG DMA can't access it, but the address of txBuffer is 0x2003EBEC which is in SRAM2. The AHB matrix in the reference manual clearly shows, that the USB OTG HS DMA is master for a bus that SRAM2 is a slave of. And DTCM is connected too. I will look for application notes for USB OTG HS DMA - it just seems to be refusing to copy data!
I have fixed my issue by disabling the DMA setting. I have re-read the relevant portions of the reference manual and still don't know how exactly the values propagate into the Tx FIFOs. It is possible that DMA-less operation will be a major bottleneck in my project, I might return to this later.