what is the point of a debugger if it does not tell me I cannot have that - Page 1
Forum section: electronics / general

author: Simon
author_rank: Unknown
timestamp: August 07, 2023, 07:20:02 pm
content: I have wasted the entire day trying to get a working counter to work as the debugger never tells me it's value, I also cannot have a variable be made equal to the counter value. This kind of makes it pointless? So I have a tool that is supposed to help yet subtly fails, so now I have to trouble shoot the trouble shooting......

author: ataradov
author_rank: Super Contributor
timestamp: August 07, 2023, 07:47:08 pm
content: You may want to provide more information on what you are trying to do. None of this makes sense.Debugging tools are not magic all-powerful things. They make some things easier and other things harder, just like other tools.But if the tool does not work for the most basic tasks, there is a much higher chance you are doing something wrong. And stating what you want to do is a much better way to approach this.

author: nctnico
author_rank: Super Contributor
timestamp: August 07, 2023, 07:48:42 pm
content: Did you compile with -O0 or -Og? If not, then optimisation will remove too much code and optimise too much for the debugger to catch every line of code. Likely your counter variable is put into a register and thus never exists as a memory location due to optimisation. I agree it sucks when trying to debug such code.

author: Simon
author_rank: Unknown
timestamp: August 07, 2023, 07:56:16 pm
content: This is a SAMC21 and an Atmel ICE, set a TC counter going, pause and what is the count in the counter? 0, but it produces PWM, so it must be counting. But i have no way of knowing if this value should show, the tool says it is 0, so what is the point if I can't trust the tool? or if there is no way to know what registers are showing their values and which are not? It's so frustrating.

author: Simon
author_rank: Unknown
timestamp: August 07, 2023, 07:56:52 pm
content: Quote from: nctnico on August 07, 2023, 07:48:42 pmcode is optimized for debuggung, I should just use a serial port.

author: ataradov
author_rank: Super Contributor
timestamp: August 07, 2023, 08:10:43 pm
content: This is not a debugger issue. On SAM C21 TC->COUNT register needs read synchronization. This synchronization is initiated by writing CTRLBSET.CMD = READSYNC. You can do that write from the debugger itself, but it is better to do it from the code before you need the value or just periodically.This behavior is described in the section 35.6.8 "Synchronization" and in the description for the COUNT register:Quote

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 03:13:06 pm
content: i see, yes I got this working with the debugger but not in the application, not that I need it in the application.

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 03:14:11 pm
content: My next cunundrum is why does it take 9 cycles to toggle a pin twice? or does the port controller not operate at the CPU speed?

author: ataradov
author_rank: Super Contributor
timestamp: August 08, 2023, 03:35:52 pm
content: How was that measured?Also, you mean the whole process of toggling twice takes 9 cycles? Then it sounds about right depending on how it was measured.There is a faster PORT version mapped into IOBUS. You can use this and it will be faster, since it won't have to go though the AHB bus. Without that PORT is just a peripheral and it has to compete for the same with the core truing to fetch instructions.

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 05:38:02 pm
content: That was with an oscilloscope, Yes I remember there are two ways to access the ports, I don't know if the header files include the definitions, I probably have some written up myself in one of my own. i guess if there are several stages of data transmission each one happens per cycle?it was more to work out how much time to take out of other measurements like how long does it take to calculate the duty cycle from stored pulse and period times. This was around 15µs with integer math and 17-30µs with floating point which is not too bad. not sure if I should bother with floating points.The difference between using inline functions and regular function calls is 200ns or around 20 cycles so 10 cycles per function call, As much as I wanted to stop using inline code I see that it has it's uses. A pity that compilers don't optimize further but I guess that complicates it too much in other situations.

author: ataradov
author_rank: Super Contributor
timestamp: August 08, 2023, 06:16:08 pm
content: Ok, but what was the code? PORT is reasonably fast, but it still takes a number of instructions to write the value and do the loop.Standard header files include those definitions. It is the same mapping, so worst case scenario - it is one #define that you need to add.I'm, not sure what you mean by stages. The device uses a shared bus, so the final behavior may depend on other things going on in the system.Compilers optimize things quite well, you just need to write code in a way that is possible to optimize. Compilers are not magic, they can only optimize things that are allowed by the standard..

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 06:52:15 pm
content: The code was literally setting the bit in the register to set/clear/toggle the pin, so as I understand it a single cycle job. So if the data has to go onto a bus that services multiple devices and then come off that bus to the peripheral does that all happen from the CPU to the port in one cycle or would it require multiple cycles for the bus to be engaged and the data transferred to the peripheral.The time I measured was for the pin to go high and then low in one round of the loop so the looping time is not included

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 06:54:21 pm
content: Oh, and luckily I read the silicon bug errata, the whatever they call it in MPLABX to run the setup of the clocks completely ignores the known bugs and the things won't work. You cannot change the RC oscillator prescaler without the clock being used, end of, this means that the code provided as standard will never work.

author: ataradov
author_rank: Super Contributor
timestamp: August 08, 2023, 07:05:25 pm
content: Quote from: Simon on August 08, 2023, 06:52:15 pmThe actual store instruction is fast, but loading the constants for the peripheral address and the value to write into the registers also takes time. So, the only way to tell what would be fast and what not is to look at the final assembly. C code may be deceptive.For the same reason, it pays to combine multiple register writes into a single function. This way all the register preparation is amortized.Quote from: Simon on August 08, 2023, 06:52:15 pmIt depends. Cortex-M0+ shares the same bus for code/data access, so the exact behavior would depend on whether currently executed code is in the flash or SRAM (due to wait states) and possibly on alignment of the 16-bit instructions inside the 32-bit word.On reset GCLK0 is cocked from the OSC48M and it requests the clock, so you can change the divider all you want. The code is tested, so it does work.

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 07:22:51 pm
content: Well granted I had to copy and modify it a bit to take it from MPLABX to studio, it failed, apparently I was trying to access an illegal address, I took everything out until the only line left in the RC clock setup was the prescaler, as soon as I moved that line to after the GCLK assignments it worked. This is inline with the errata.it's a bit like the PLL bug, the PLL has to be allowed to drift or the whole application fails.

author: ataradov
author_rank: Super Contributor
timestamp: August 08, 2023, 07:52:43 pm
content: That errata would not cause device misbehavior. All it will do is permanently set the SYNCBUSY bit, which you would instantly see if you wait in it.There was something wrong with your code.

author: Simon
author_rank: Unknown
timestamp: August 08, 2023, 08:43:21 pm
content: Yes it got stuck in the sync busy, having removed that check instead of getting stuck there I got this very odd error. I took that line that was left and by moving it to the same place I had always put it by accident, and it worked, not that I want to use the RC oscillator at this stage anyway.

author: westfw
author_rank: Super Contributor
timestamp: August 09, 2023, 12:00:08 am
content: QuoteTo modify a pin on most RISC architectures usually requires at least three instructions:Load address of port register into a CPU register. This usually accesses data in flash and can take more than one cycle.Load info about pin within the port into another CPU register. Usually a bitmask. This could also be a flash constant, or on CM0 could be a MOV (immediate value) instruction followed by a bitshift to get it in the right place (M0 can only load 8bit immediates)Store the bit-info register via the address register. Since the peripheral may be on a slower peripheral bus, this can also take more than one cycle. Using IOBUS registers instead of APB register can speed this up. If your chip has IOBUS (SAMC20 does seem to have it.)Depending on optimization and peripheral implementation, some of that can be shared - "toggle twice" might load the two constants and then do two consecutive stores to the "port bit toggle register." Or not; check the assembly listing to be sure.

author: eutectique
author_rank: Frequent Contributor
timestamp: August 09, 2023, 08:35:23 am
content: Quote from: westfw on August 09, 2023, 12:00:08 amSome Cortex-M3 and M4 chips implementbit-banding. This eliminates the need for RMW cycle.SAM C21 is M0+ though.

author: Simon
author_rank: Unknown
timestamp: August 09, 2023, 08:38:17 am
content: Yes at 48MHz there have to be 2 wait states on the flash. I used 1 wait state as a test which I know works at room temperature but should not be done in the final application and it shaved 15% off the time. So flash wait states have some influence but not too much.

author: Simon
author_rank: Unknown
timestamp: August 09, 2023, 08:39:50 am
content: Quote from: eutectique on August 09, 2023, 08:35:23 amThe peripherals do this. There is a pin set, clear and toggle register for each port. 0's are ignored, you send a 1 to have the effect of the register on the bits of interest without upsetting the others.

author: ataradov
author_rank: Super Contributor
timestamp: August 09, 2023, 02:53:40 pm
content: There is no interface on the M0+ for nit-banding. IOBUS version if the PORT is all you get.

author: Simon
author_rank: Unknown
timestamp: August 09, 2023, 03:24:11 pm
content: Well I emailed microchip support about the 92MHz on the TCC for the SAMC and the suggested the SAMD5D/E series. I took a quick look at the datasheet and it looks pretty good, 3x the speed M4 with FPU and the same peripherals. At this point I wonder, was the SAMC line a bit of a dead end? I have perused the SAMD10/11/20/21 series and always took them to be the USB/commercial version of the SAMC that is aimed at automotive, but the same series includes an M4 core? If I remember rightly the SAMD10-21 registers were not necessarily the same for the counters, I have not compared to the SAMD5 yet but I'm glad there are some familiar peripherals in there.

author: ataradov
author_rank: Super Contributor
timestamp: August 09, 2023, 04:21:12 pm
content: Quote from: Simon on August 09, 2023, 03:24:11 pmSAM C devices are cheaper and support 5 V operation. They are by no means a dead-end. The continuation of that series happens with PIC32CM JH00/JH01.Quote from: Simon on August 09, 2023, 03:24:11 pmI always looked at it as an automotive version of the rest of them. It is a matter of perspective, I guess.Quote from: Simon on August 09, 2023, 03:24:11 pmIt is really the same series just in the name. And SAM E5x/D5x will continue development as PIC32CX SG41/SG61.

author: Simon
author_rank: Unknown
timestamp: August 09, 2023, 04:51:22 pm
content: This is what makes it so difficult and microchip seem to fail badly at naming conventions and the like with Atmel about as bad. First they named a totally new AVR series as the mega, the only clue was that it was series 0 mega, but try telling google that, I guess they then realized their mistake which was obvious from the start and created the AVR A, B, C, D series or something like that.So Atmel called rather different products by the same name? I mean the communality of the peripherals is a great start. One day will these people get that the processor is the last thing on our minds? I'm more interested in a device that has the same peripherals so that old code remain compatible and my knowledge of the device. As in this case I consider what about when I want a faster CPU, my dread is that to get a faster CPU I have to abandon all knowledge of the peripherals and start again. A change in CPU has far less impact than a change in peripherals as that is the compilers problem not mine.If only manufacturers understood and advertised the cross compatible parts instead of playing roulette with the part numbers.

author: Simon
author_rank: Unknown
timestamp: August 09, 2023, 05:06:15 pm
content: Of course searching for anything on the microchip website is totally hopeless, the search feature refuses to get series names and will only find results when a precise part number is entered.

author: errorprone
author_rank: Contributor
timestamp: August 09, 2023, 09:06:34 pm
content: I’ve found microchip maps better than their normal website for search.https://www.microchip.com/maps/Microcontroller.aspx

author: westfw
author_rank: Super Contributor
timestamp: August 11, 2023, 05:54:11 pm
content: QuoteThat doesn't change the basic timing I described. If you use a chip with neither bit-banding NOR set/clear registers for GPIO, you can add at least one more instruction to read the old port register contents (and probably another one or or/and your bit with the read contents.)SAMC has set/clear/toggle GPIO registers, and IOBUS, so that's the way to go if you're looking for maximum performance.ARM Microcontrollers from vendors with half-a-clue almost always have the set/clear GPIO registers.

author: cv007
author_rank: Frequent Contributor
timestamp: August 11, 2023, 09:39:22 pm
content: QuoteThat seems to be something that gets overlooked- any method requires getting a value into a some register, which does not happen on its own (needs instructions to setup).Although the set/clr/tgl registers can speed things up due to assignment-only use, their main purpose is to keep the bit manipulation atomic. The sam has these registers, which allow any code (+interrupts) to manipulate pins without the need for all code to protect the bit manipulation (since pin register bits of a port typically live inside the same register). The iobus in this case is for speed, the set/clr/tgl is for atomicity.The port registers are usually somewhat unique in that various pieces of code can be manipulating pins which typically share a register. The addition of set/clr/tgl registers eliminate the need to interrupt protect each use. There are other pin properties that may share registers on some mcu's, such as an stm32 which cannot change a pins properties atomically (so if you manipulate these property registers the safe thing to do is interrupt protect them).For a SAM, I believe the only port registers to otherwise worry about are the pmux registers (8bit register, shared by 2 pins), but there is a wrconfig register that can take care of dealing with pmux in an atomic way. An EFR32/EFM32 has set/clr/tgl for all peripheral registers so is easy to do any register writing atomically (whether needed or not). A Renesas RA has a set/reset port register but they also have a single PFS register for each pin that contains most of its properties/state so any manipulation is isolated to a single pin and becomes similar to the typical peripheral register (no need to protect). The Renesas library uses the PFS register for pin writes, so is rmw but no other pin is affected (they seem to only use the set/reset register for writes to multiple pins).

author: westfw
author_rank: Super Contributor
timestamp: August 12, 2023, 02:49:13 am
content: QuoteThey certainly help with speed as well, ESPECIALLY if you need to ensure atomicity! (None of the instruction sequences mentioned includes any additional atomicity handling, although it's inherent if you have either bit banding or set/clr/tgl.)One thing I don't see taken advantage of very often is that some chips (including SAMC, I think) have byte-addressable GPIO peripheral registers, even though the ports themselves are wider. Theoretically, this could save a bit if you're using the high bits in a port, since you can always "MOV" an 8bit constant, but getting things in the upper bits is more expensive. (Alas, the provided .h files don't define byte-wide access to the ports.)

author: Simon
author_rank: Unknown
timestamp: August 12, 2023, 01:06:59 pm
content: Yes I had considered adapting my text screen code to work across an 8 bit "port" rather than do each bit in turn. Does mean I'd have te be careful about pin multiplexing so not bothered so far.

author: westfw
author_rank: Super Contributor
timestamp: August 12, 2023, 07:14:44 pm
content: QuoteSAM microcontrollers do not seem to be very good at making available consecutive bits of IO ports.I specifically complained about SAMD10 (etc) here:https://forum.microchip.com/s/topic/a5C3l000000UdT7EAK/t164828(There are no 8bit ports with 8 consecutive pins.)The RPi Pico folks implemented a neat way to set bit-fields in a port without affecting pins that belong to "something else", using a read/xor/toggle:https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_gpio/include/hardware/gpio.h#L718(which should work on any device with a "toggle" capability.)