Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Spatial
Nov 15, 2007

Dominoes posted:

Btw, do y'all have any recommendations for how to read and write small amounts of data using an STM32? Ie reading and writing a handful of numbers to a config "file" during program operation. Am I looking for Flash memory? DMA? SRAM? I can probably find an appropriate HAL lib once I know where to start.
For nonvolatile memory NOR SPI flash is your basic goto. If it's extremely infrequent access you can probably use the flash memory in the actual chip but there are a lot of caveats there.

Also, earlier you were wondering about the SWO pin on the SWD debug interface. This is normally used as a low-overhead debug console output that prints directly in an IDE window. It's nice to have.

Adbot
ADBOT LOVES YOU

Spatial
Nov 15, 2007

What's a decent chip for audio output? At the moment I'm using a CS4344 directly attached to a pair of headphones. It's fairly quiet I'm guessing because it's supposed to be paired with an amplifier. Still, cool as hell to hear it working. :)

I noticed you can get ICs with an integrated headphone driver (e.g. MAX9850). This fits my requirements like a glove as far as I can see:

- 2x stereo outputs: headphones + line-out
- 48 KHz stereo I2S input
- 3v3 power
- I2C controlled

Any gotchas there?

Spatial
Nov 15, 2007

Ideally no controls at all would be best, like the CR4344 where it just determines the sample rate from the clock, but most multimedia stuff seems to be I2C so it's hard to avoid. I don't have a free SPI bus to use either.

But yeah I'm used to that kind of nonsense, it's actually my job :v:

Spatial
Nov 15, 2007

There's a lot that can go wrong with I2C, it trades wires for extra complexity. I can hardly remember a single chip I've worked on that didn't have some serious I2C errata. Clock stretching is a common favourite. One is nearly EOL at this point and they still find new bugs in it lol

I've written drivers for some pretty lovely SPIs as well though. One was so bad it took multiple months to get it 100% stable - just an endless stream of timing bugs that would only trigger after tens of hours of testing. Total garbage.

Spatial
Nov 15, 2007

I actually managed to get my hands on the hardware designer's testbench for that SPI peripheral; all the tests were in loopback mode, single transfers, with full chip resets between each test. Truly designed for reliability

Spatial
Nov 15, 2007

Yep. v:shobon:v

Spatial
Nov 15, 2007

The MPU in Cortex-M is used for setting certain memory regions as read-only, no-execute, etc. Very useful since any violation immediately triggers the MemManage interrupt and sets registers which tell you the address of both the illegal access and the instruction. Good debuggers can automatically catch the interrupt and do the fault analysis for you which is a great help.

Hopefully this is less necessary when using Rust though! :)

Spatial
Nov 15, 2007

Dominoes posted:

Related: Do the small headers that connect to ribbon cables have a name I can search for?
They're called FFC connectors. Flexible flat cable

E: sometimes also FPC

Spatial
Nov 15, 2007

Does it matter which way the differential signals of an Ethernet PHY are connected to the isolation transformer? Example with just the relevant signals connected:



Let's say you swap +/- on the left. Does it still work? Why or why not? :frogdunce:

Spatial
Nov 15, 2007

These magnets aren't magic? :mad:

But is totally fine to flip the signals on both ends, right?

Spatial
Nov 15, 2007

Forseti posted:

I think you should be fine flipping both of them. Just curious, I'm guessing this makes the board routing easier? :)

Edit: Well, assuming it's actually just a transformer and doesn't have diodes or something in there.
Busted. :v: I had to change the connector after already going through the process of laying out the whole thing.

Yup, pure transformer. Pretty cool looking too, I got these surface mount ones TDK makes:

Spatial
Nov 15, 2007

I know about those, much easier to deal with! I can't use a magjack for this because the ones I can source are all far too tall for the design. I spent ages looking for low profile ones.

These TDK transformers are tiny, 3.2mm square, so overall it works out to about the same board area.

Spatial
Nov 15, 2007

I've got a few odd valued ceramic capacitors in my design. I want to make the BOM simpler/cheaper by using smaller caps in parallel, summing up their capacitance values. They all have the same dialectric and voltage rating so it should be okay in theory right? In fact even better since the ESR is lower I think???

Two examples would be:
2.2uF -> 10 + 10 + 0.22
33uF -> 10 + 10 + 10 + 1 + 1 + 1

The last one may be slightly silly but it's still much cheaper and there's plenty of space. :)

Spatial
Nov 15, 2007

One is a regulator output so that doesn't particularly matter as long as it's above the target value. The others are the kind of thing where a datasheet says "use this cap" and doesn't explain it so I don't want to deviate much on those

Spatial
Nov 15, 2007

Fair enough :)

Spatial
Nov 15, 2007

The values aren't unusual, I meant they're odd ones out in the BOM. It's just easier/cheaper to build the board with fewer unique parts.

Yeah I see your point with the tolerances... I guess I may as well just round up with the biggest size in the group.

Spatial
Nov 15, 2007

Stack Machine posted:

:doh: that makes a lot more sense.

One thing you can do is compute new tolerances for your aggregate devices and see if they're OK. Like a "22uF" made of 2 10uF caps will have a minimum value of 16uF with 20% components and a maximum value of 24uF and so you could claim it behaved like a "22uF" cap with 27% tolerance. Or you could get tighter-tolerance caps for the values you're doubling/tripling up. 2 10uFs at 10% is like a 22uF at 14%, etc.
Good point! I'll stick with the 10% ones to keep it sane.

Spatial
Nov 15, 2007

On a separate topic, I've been working a tiny board for my own general use recently. I wanted to make it really small and cheap but still practical. It's based around the pretty new STM32G03 which is a 64Mhz M0+. Adding to that are an external DAC, 2MB of SPI flash and a few LEDs and buttons. Powered over USB or through the headers.


I got the boards back and tried out some solder paste stencil + reflow last night, which I've never done before. My highly expensive and complex reflow system: a bargain bin kitchen hot plate and a 50 cent thermocouple.


My results with the stencil were middling, it's all too easy to add too much paste and make a mess of it. Balls of solder underneath the caps etc. I messed up by not shrinking the holes in the stencil a bit, they're the same size as the pads. Duhhhhh. Next time!

I got the best results by smearing teeny-weeny amounts of paste on the pads with an even tinier stick. This worked shockingly well and didn't even take long. Using fine tweezers even the 0402s weren't a problem! For the 32-pin MCU I just smeared it thinly across the pads and it magically flowed into place when it melted. Really neat looking when it happens.

Here is the result with bare minimum populated parts and some random headers I had laying around. Reflow result looks great compared to doing it with an iron.


Further along, everything is mounted except the overly-tiny buttons. Was able to program it successfully and it's blinking away! The board is solid enough that I can run the SPI flash at 32 MHz. I'm really happy it turned out so well! :holy:

Spatial
Nov 15, 2007

Thanks! Yeah it's just me turning the knob and keeping an eye on the temperature :v:

Thermal hackery could be a fun project and I might give it a go sometime. I know many people have done custom reflow ovens based on toaster ovens and stuff like that.

Spatial
Nov 15, 2007

Dominoes posted:

Hey dudes. On ARM processors, does running a loop itself, eg to check for inputs, use a sig amount of power/battery life? I'm trying to figure out the best way to maximize battery life on a device that needs to poll sensors as-required, but always be ready for a button input. Delay is one way to save battery life, but need to work out a clever way to poll (or check for a hardware signal?) from buttons etc. Do those free-running loops that poll pins but don't do much else use lots of power/battery, or do they need delays?
Whenever code is running power consumption is at maximum, low power states save so much power because they stop the core. As others mentioned, this is why reducing the duty cycle of the core by far the most crucial thing to do.

You can get an idea for other things to squeeze from the datasheet. Power consumption is linearly proportional to the clock frequency and this figure is usually given in uA/Mhz (it also increases the duty cycle since it takes longer to do things though). Integrated periphals like timers, UARTs and the like also have a constant power cost when enabled so turn off anything you don't need. Running code from flash also costs more power than running from SRAM, if you can fit it in there.

Spatial
Nov 15, 2007

That write will zero everything else in the register which is probably fatal. You need to read the current value, modify the bit, then write it back. E: Your edit looks better.

The very lowest power modes have lots of gotchas so you need to read about them carefully. Many peripherals will lose their state, SRAM may not be retained or only in some banks, you may have to wait for comm peripheral TX FIFOs to empty etc. Start with the modes that are easier to manage. You can go a long way with just stopping the core since it uses by far the most power.

Another thing that's worth bearing in mind: you can't test low power modes with a debugger active. When connected the instructions that enter low power states act as NOPs, otherwise it would power down the core's debug access port. A logic analyser and some GPIO toggles are helpful for this.

E: Oh yeah I forgot to mention, the RTC is your friend for low power modes. The RTC can remain active in all power modes and uses very little power itself, and it can wake the core with an interrupt at a preprogrammed time.

Spatial fucked around with this message at 21:25 on Jun 20, 2020

Spatial
Nov 15, 2007

I used an I2C IO expander in my current design and now I kinda wish I just used a microcontroller with an I2C slave port instead. Half the cost, twice the pins and a million extra peripherals. Only downside is I have to program it!

Spatial
Nov 15, 2007

Dominoes posted:

Just need it so I can use a low power state + RTC Wakeup every second or so vice a delay to save battery life, and maybe maintain a calendar/clock for logging measurements...Little precision required.
Do you even need a crystal then? If you don't need high precision you can use the built-in low frequency RC osc, no need for any external components.

Spatial fucked around with this message at 20:54 on Jul 16, 2020

Spatial
Nov 15, 2007

Another little project report!

In the last couple of days I built something neat for my fiance, a set of media buttons so she can control music playback without having to open her laptop. I actually wound up using it myself too :v:



It's based around the STM32F042. It's a USB HID device so it shows up as a keyboard with media keys. No crystals needed since the chip can trim its RC oscillator off the USB sync signals. :)

The buttons light up around them when pressed. For this I hooked up all five LEDS to one resistor and have the switches directly control them, connecting to ground when pressed. Another LED shows USB activity near the micro B port. It also comes on dimly on unprogrammed boards so I can quickly see if the board connections are solid. I got a bit too stingy with the solder paste one time!

The hardest part software-wise was trying to comprehend the USB spec to make the USB report descriptors. Media keys aren't normal keyboard keys but instead fall under the "consumer control device" spec which is a bit more obscure.

I wanted it to be enclosed in a case but I don't know anything about 3D printers or modelling so I took the somewhat unusual (I think?) approach of making the case out of multiple layers of PCBs and using steel dowels to keep them aligned. This is cheap enough that it's practical although it's kind of a pain to cut the dowels to length with the equipment I've got. Once assembled it's held together with small droplets of glue on the dowels and board sides that soak into the PCB edges. Very strong and feels comfortably solid and weighty.

The layers:


I missed a trick with the button LEDs. They shine up through the small gaps around the buttons, but it occurred to me after that I could make a glowing ring around them because PCBs are semitransparent if you leave off the copper and mask layers. Next time!

Spatial
Nov 15, 2007

Sagebrush posted:

very cool idea

it is driving me apeshit that the volume buttons aren't vertically aligned
Ha! That's intentional, it's the same angle as the angled edge of the case. :)

Spatial
Nov 15, 2007

Trying to connect two microcontrollers together via USB OTG to do serial communications is straight up Onion article material my man

Spatial
Nov 15, 2007

Yeah UART is by far the easiest thing to do. Hook up two wires and you can be sending bytes back and forth in no time at all. No special transceivers, no external devices, you don't even need a crystal to use typical UART buad rates.

Spatial
Nov 15, 2007

A USB device which doesn't respond for seconds at a time is going to cause quite a lot of problems. It probably has nothing specifically to do with acting as a COM port.

When you say are polling the serial connection, I'm guessing you're calling into a driver which actually does a lot of things like handling enumeration and servicing the USB peripheral in general. That's often how code like that is generated. Practically you likely need to invoke that servicing through a timer callback on a regular interval like every 10ms, seperate from regular program flow.

Spatial
Nov 15, 2007

All you need is to run the USB routine in an interrupt from a timer.

Spatial
Nov 15, 2007

PSA: There's an extremely useful tool which can generate Kicad schematic/library files directly from a PDF datasheet called uConfig.

Spatial
Nov 15, 2007

I wouldn't recommend using a library for this since learning how it's done will teach you some useful info.

Keeping it simple, a good starting point is to define a fixed data structure which can represent all possible commands. Prepend this with a sync pattern so you can detect the start of a frame. Append a CRC so you can discard bad frames. Then send these frames over the UART. On the receiving end you scan for the sync pattern to detect the beginning of a frame and put the bytes in a buffer. When you have a full frame you verify its CRC and if it's good you parse the commands and take action.

Example frame:
code:
struct UartFrame {
    u8 sync;
    u8 command;
    u8 data;
    u8 crc;
};
Sending a command:
code:
void sendAdcPowerCommand( bool state ) {
    UartFrame frame = { SyncPattern, AdcPowerCommand, state, 0 };
    frame.crc = calcFrameCrc( &frame );
    uartTx( frame, sizeof(frame) );
}
For receiving you use a simple state machine. Probably best driven from a callback which gives you a byte at a time in this example.
C++ code:
u8 fsmState = Idle;
u8  buffer[ sizeof(UartFrame) ];
u8* index = 0;

bool bufferFull( void ) {
    return index >= sizeof(buffer);
}

void uartRxCallback( u8 byte ) {
    switch (fsmState) {
        case Idle: {
            if (byte == SyncPattern) {
                fsmState = Receiving;
                buffer[0] = byte;
                index    = 1;
            }
        } break;
        
        case Receiving: {
            // Drop frame if it would overflow
            if (bufferFull()) {
                fsmState = Idle;
                return;
            }
            
            // Update buffer
            buffer[index] = byte;
            index++;
            
            // Enough data for a full frame?
            if (bufferFull()) {
                fsmState = Idle; // Done
                
                // If valid, use the frame
                if (checkCRC()) {
                    parseBuffer();
                }
            }
        } break;
    }
}
Once you get this far you can then add some simple ACK/NAK responses to make it reliable in the long term. Congratulations on your new robust communication protocol!

Spatial fucked around with this message at 23:02 on Nov 25, 2020

Spatial
Nov 15, 2007

I like UART because it has two asynchronous channels and basically behaves like Ethernet with infinitely large frames and no error checking. :v:

Spatial
Nov 15, 2007

Sure. I've had all sorts of weird shapes made. It doesn't cost extra, actually it's so cheap that sometimes I just have stands for things manufactured in a PCB fab with no copper lol.

Check out the middle one here:

Spatial
Nov 15, 2007

Talking about switching regulators, TI also make some really tiny ones which have the inductor mounted on top. 3x3mm!

Spatial
Nov 15, 2007

That hosed me pretty good on my first batch of boards.

KiCad has a per-board global setting for soldermask which controls its minimum width, and by default this is relatively large so if you have small pad geometry it will strip away everything between pads before the fab even gets to attempt to make it. As an added bonus this only shows in the gerber output, not any other view.

Ever since I set that to zero I've had no problems with shorts even with the tiniest parts. Also I learned to always check the gerbers. :v:

Spatial
Nov 15, 2007

The ideal project is one where you can have all the fun developing it, get paid, and never have to support it. If it gets cancelled early enough you won't even have to test it and admit it has flaws, and everyone will appreciate your genius all the more!

Spatial
Nov 15, 2007

Another common case is CRC/hash peripherals. Can also be used for async memcpy in some cases.

Pretty much always worth using. You can acheive much faster transfer rates than by polling and with much less CPU usage. Usually you can put the core to sleep while the DMA continues to run for fairly large power savings too.

I wouldn't even spit on a microcontroller without DMA

Spatial
Nov 15, 2007

Fritzing is horrendous for all but the simplest boards. It was the first CAD software I used, and I used it to make exactly one board before trying KiCad and never looking back.

It is good for laying out breadboards though!

Spatial
Nov 15, 2007

Clearly you should implement the M7 core on a Zync Ultrascale+ FPGA

Adbot
ADBOT LOVES YOU

Spatial
Nov 15, 2007

I actually made a video upscaler on a small FPGA lately, I should do a writeup

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply