<rqou> anyone know of a nice and simple hdl uart module i can copypasta?
<azonenberg> rqou: verilog ok?
<rqou> sure
<rqou> something that yosys can accept
<azonenberg> Havent tested on yosys but i've used it on ISE etc for ages
<rqou> target is ice40
<azonenberg> the `define's really should be refactored to parameters, i didnt know about parameters and generate blocks when i first wrote the code :p
<azonenberg> but it works
<azonenberg> the majority voter could also be rewritten far more concisely
<azonenberg> (i havent gotten to that core as part of my antikernel cleanup rampage yet)
<rqou> what's the oversample factor? 8x/16x/something else?
<rqou> er, 5x?
<rqou> wtf?
<azonenberg> i wanted an odd number for majority voting to have a deterministic answer
<azonenberg> and 5x fits nicely in one lut
<rqou> ah neat, except not on ice40 :P
<azonenberg> (on 7 series at least)
<azonenberg> I plan to rewrite it with parameterizable oversampling down the road
<rqou> yeah i don't care about that
<azonenberg> basically all of my existing IP is being either majorly tweaked or rewritten from scratch
<rqou> i expect to run at either 1mbaud or 2mbaud and have a clock error of 0%
<azonenberg> since i've learned so much about fpga stuff since 2010 :p
<rqou> so it won't need it nearly as much
<rqou> i just need a "herp derp, i can haz bytes" uart
<ZipCPU> rqou : I do have one that has been tested on #yosys.
<rqou> too many features :P
<ZipCPU> There's on with almost no features within that set.
<ZipCPU> Look at txuartlite.v and rxuartlite.v
<ZipCPU> Both implement 8N1 ... with no features.
<rqou> lol ok
<azonenberg> Thats what mine does basically
<azonenberg> 8N1 with no flow control
<azonenberg> minimal fluff
<rqou> how about 9N1? :P :P
<rqou> or what's that weird smartcard mode? 8N1.5?
<rqou> but yeah, this isn't what i'm doing
<ZipCPU> 8N2 would be easier.
<rqou> i just want "plz to read from PC"
<rqou> iirc smarcards wanted 1.5 stop bits because reasons
<ZipCPU> 8N2 TX, 8N1 RX and ... you're good to go with a 1.5 stop bit interface
<rqou> yeah i don't seriously need a smartcard-compatible uart
<rqou> azonenberg: for a future project, got a barebones SPI too?
<azonenberg> this one has actually been cleaned up a bit
<azonenberg> these two are master only but slave support could probably be added without much work
<rqou> alright, good enough for now
<rqou> although i might want an i2c slave at some point later
Zarutian has quit [Quit: Zarutian]
azonenberg_work has joined ##openfpga
DocScrutinizer05 has quit [Disconnected by services]
DocScrutinizer05 has joined ##openfpga
eduardo_ has joined ##openfpga
eduardo__ has quit [Ping timeout: 240 seconds]
azonenberg_work has quit [Ping timeout: 240 seconds]
azonenberg_work has joined ##openfpga
digshadow has joined ##openfpga
<rqou> offtopic: anybody know what can cause white residue to appear on a PCB when I attempt to remove flux using isopropanol?
<rqou> any good fixes/alternative solvents?
<azonenberg> My guess: salts from the flux
<azonenberg> I've had it happen too
<azonenberg> It can happen with acetone sometimes too, and that is strong enough it may damage some soldermasks or silkscreen
<azonenberg> i generally just scrub as much as i can and leave it
scrts has quit [Ping timeout: 260 seconds]
scrts has joined ##openfpga
DingoSaar_ has joined ##openfpga
azonenberg_work has quit [Ping timeout: 260 seconds]
<rqou> would you recommend i just change flux chemistry?
<azonenberg> that might work
<azonenberg> um, sec
DingoSaar has quit [Ping timeout: 268 seconds]
<azonenberg> i have some of this and reclal it not leaving much residue
<azonenberg> mixture of ethanol, ipa, and ethyl acetate
<rqou> hmm where can i easily order that?
<azonenberg> comes both in aerosol and bulk liquid
<rqou> wtf amazon
<rqou> well, that's nice
<azonenberg> i normally just use ipa
<azonenberg> but here and there if i have a stubborn mess i want gone i pull this stuff out
<azonenberg> the ethyl acetate must help with the bits the alcohol wont remove
<rqou> what flux do you use?
<azonenberg> i doubt the ethanol and ipa are all that different in activity
<azonenberg> the ipa is likely just a denaturant
<azonenberg> i use chipquik smd291nl
<azonenberg> plus whatever is in my solde rpaste
<azonenberg> i have some chipquik smd291snl but its old, may have thrown it out
<azonenberg> recently i've been using kester lead-free paste from oshstencils
<azonenberg> i forget the SKU
<rqou> so i have MG chemicals no 8341 for flux and mg chemicals no 4875 for solder
<rqou> still need to buy some paste
<rqou> if you look up that solder you might find that i was (still am?) quite a cheapskate :P
<rqou> (it's non-eutectic 60/40 sn/pb, not even 63/37)
<azonenberg> lol
<azonenberg> i use sac305 exclusively now
<azonenberg> i think i have a roll of 63/37 i use for the rare occasions i have to mess with lead
<azonenberg> but i dont even remember the last time i used it
<rqou> but we're in the land of FREEDOM where we can just use lead everywhere :P
<rqou> also, i use leaded solder to assist desoldering :P :P
<rqou> intermetallics? what are those? :P
<azonenberg> lol
<azonenberg> see, i have sac305 balled bgas
<azonenberg> and i want my boards to last :p
Bike has quit [Quit: fall]
<rqou> hmm, how evil is it to use RTS/DTR to control extra states in my fpga?
<azonenberg> it's been done
<azonenberg> personally, i'd run a debug protocol over jtag :pp
<rqou> ice40 :P
<azonenberg> for that i'd use a ft232h and do spi
<azonenberg> or 2232h
<rqou> too much work on host end
<azonenberg> is the fun you get to have when you can do jtag in the fpga :D
<rqou> alright, time to check my .pcf using the tried-and-trusted technique of "highlighter-aided design"
scrts has quit [Ping timeout: 260 seconds]
m_t has joined ##openfpga
lain__ has joined ##openfpga
lain has quit [Ping timeout: 260 seconds]
scrts has joined ##openfpga
qu1j0t3 has quit [Ping timeout: 240 seconds]
scrts has quit [Ping timeout: 260 seconds]
scrts has joined ##openfpga
qu1j0t3 has joined ##openfpga
_whitelogger has joined ##openfpga
lain__ has quit [Quit: WeeChat 1.7.1]
lain has joined ##openfpga
knielsen has joined ##openfpga
Zarutian has joined ##openfpga
X-Scale has quit [Quit: HydraIRC -> http://www.hydrairc.com <- It'll be on slashdot one day...]
Bike has joined ##openfpga
pie_ has joined ##openfpga
azonenberg_work has joined ##openfpga
LeelooMinai has joined ##openfpga
digshadow has quit [Quit: Leaving.]
LeelooMinai has left ##openfpga [##openfpga]
amclain has joined ##openfpga
azonenberg_work has quit [Ping timeout: 260 seconds]
hobbes`` has joined ##openfpga
qu1j0t3 has quit [*.net *.split]
dingbat has quit [*.net *.split]
promach has quit [*.net *.split]
hobbes- has quit [*.net *.split]
hobbes`` is now known as hobbes-
qu1j0t3 has joined ##openfpga
dingbat has joined ##openfpga
digshadow has joined ##openfpga
azonenberg_work has joined ##openfpga
promach has joined ##openfpga
digshadow has quit [Quit: Leaving.]
<rqou> (playing with Rust) wow, bindgen is pretty good and can handle basic C++
digshadow has joined ##openfpga
<ZipCPU> rqou: You asked about a bare bones SPI. My big problem with that is that every peripheral controller I've come across seems to use the chip select in a different fashion.
<ZipCPU> Still, I have a bare bones QSPI flash reader, if you are interested in that.
<rqou> i don't care about chip select because i always have to end up manually controlling it
<ZipCPU> I've also got a bare bones lower-level SPI protocol runner ... so if you only want the lower level stuff ... yeah, I've got a bare bones one of those.
<rqou> hmm, rust bindgen seems to have trouble with nested namespace definitions
<rqou> which clang tells me "nested namespace definition is a C++1z extension"
<rqou> and gcc silently accepts
<rqou> typical
digshadow has quit [Ping timeout: 245 seconds]
digshadow has joined ##openfpga
digshadow has quit [Quit: Leaving.]
scrts has quit [Ping timeout: 240 seconds]
scrts has joined ##openfpga
pie_ has quit [Changing host]
pie_ has joined ##openfpga
scrts has quit [Ping timeout: 260 seconds]
scrts has joined ##openfpga
digshadow has joined ##openfpga
m_t has quit [Quit: Leaving]
scrts has quit [Ping timeout: 240 seconds]
scrts has joined ##openfpga
digshadow has quit [Quit: Leaving.]
DocScrutinizer05 has quit [Quit: EEEEEEK]
DocScrutinizer05 has joined ##openfpga
ZipCPU|Laptop has joined ##openfpga
<qu1j0t3> this might interest somebody https://www.cs.utah.edu/~regehr/papers/ssv10.pdf
<qu1j0t3> formal verification / drivers
<azonenberg_work> oooh
<qu1j0t3> of course i stole it from a conversation whitequark is havnig on twitter
<whitequark> azonenberg_work: is there anything like USB-DFU but for TCP?
<whitequark> or really anyone:
<azonenberg_work> whitequark: TFTP is the closest i'm aware of
<whitequark> ugh
<azonenberg_work> that's what e.g. cisco router recovery modes use
<azonenberg_work> i do not believe there's a firmware update standard for ethernet based protocols like there is for usb
<whitequark> >TFTP defines three modes of transfer: netascii, octet, and mail.
<whitequark> >mail
<whitequark> what
<azonenberg_work> octet is basically the only one anyone uses anymore
<azonenberg_work> at leasti n my experience
<azonenberg_work> b/c nobody uses tftp except for PXE and remote firmware updates
<azonenberg_work> If i were to implement a LAN-reflashable device i'd likely use TFTP to push a signed image file over
<azonenberg_work> have the device cache locally, verify the sig, then burn it if it's good
<whitequark> I don't have enough RAM to store the entire firmware
<whitequark> for one
<azonenberg_work> Flash?
<whitequark> well
<whitequark> I could hack around it, sure
<azonenberg_work> you could write to the high half of flash then if the checksum is good copy to the low half
<azonenberg_work> or something like that
<azonenberg_work> or, as a last resort
<azonenberg_work> bulk erase flash, burn the image, checksum
<whitequark> that means that a reset in the middle leaves the device unbootable
<azonenberg_work> if the checksum fails repeat the download and just hope it's successful before the nextp ower cycle
<azonenberg_work> correct
<whitequark> at least not over the network
<whitequark> that's gross
<azonenberg_work> that happens no matter what your updaet alg is if you don't have enough memory for two copies
<azonenberg_work> If you have enough flash for two copies, you can have a fallback
<whitequark> well, no
<azonenberg_work> xilinx fpgas have boot fallback in hardware already
<azonenberg_work> with an mcu you can do it in a bootloader
<whitequark> I could have a bootloader
<azonenberg_work> it could be as simple as, check a certain address to see if it's 0xff
<whitequark> I wonder how large smoltcp would be in a minimal configuration
<azonenberg_work> if not, jump to it
<azonenberg_work> otherwise jump to a diff address that has a recovery image
<lain> in the past I've written a bootloader (dedicated bootloader region in flash) that overwrites current firmware with new firmware, but only sets the valid bit in flash if the checksum matches or etc
<azonenberg_work> lain: the issue is to avoid bricking the device on a failed flash
<azonenberg_work> the only viable option is to have a fallback firmware
<lain> azonenberg_work: it wouldn't be bricked, the bootloader is always present
<lain> the bootloader never erases itself, it just erases everything else
<azonenberg_work> So then the bootloader is your fallback firmware
<azonenberg_work> as long as it still implements an update algorithm
<lain> but this was on a chip with a dedicated bootloader region and a flash erase command that, allegedly, can't erase the bootloader :P
<lain> right, the entire update process is implemented in the bootloader in my suggestion
<azonenberg_work> sure, that works nicely if you have it
<lain> and then if I need to save space I just call through the bootloader to reuse routines where possible :P
<lain> but yeah the A/B firmware route is another way to go, just have two full firmware regions and swap the pointer when the new one is validated
<lain> that also lets you trivially set a "first boot of new firmware" flag and if the boot process doesn't set another bit within some watchdog timeout, you can fall back
<whitequark> this chip actually has some provisions for that
<lain> it's when you have to patch the bootloader that things get really scary :D
<azonenberg_work> lain: that s how xilinx fpga multiboot works
<azonenberg_work> except the "bootloader" is hardware and cant be patched
<lain> azonenberg_work: ah yeah
<azonenberg_work> its just a state machine that boots from one location then if that fails tries the other
<whitequark> lain: hm, that's a good point
<whitequark> if you have a robust process for doing the A/B update process
<whitequark> you are never stuck with an outdated or broken bootloader
<azonenberg_work> Yep
<azonenberg_work> Your "bootloader" can be a single jmp instruction
<azonenberg_work> that you patch after verifying a good update :p
<lain> yeah
<azonenberg_work> Although you probably want the fallback etc in the bootloader too but it can still be made super simple
<azonenberg_work> and need not actually implement the update algorithm itself
<lain> and if you don't have a separate bootloader, you can implement the "new firmware didn't boot" failsafe by jumping to new firmware live without patching flash, then make the new firmware write the new jmp instruction to flash after a successful boot, or etc
<lain> I often see that initial jmp referred to as a trampoline :3
<whitequark> you don't need a jmp on cortex-m even
* azonenberg_work bounces on lain's trampoline
<whitequark> just reprogram the start pc(/sp)
<lain> haha
<whitequark> lol azonenberg_work
<azonenberg_work> whitequark: yeah you could just rewrite teh vector table
<azonenberg_work> but you'd also have to patch all of the other offsets for ISRs
<azonenberg_work> the other thing i see done is, you have the intiai lvector table jump to a trampoline
<whitequark> what do you mean?
<azonenberg_work> which then jumps to a stub in the A or B image
<azonenberg_work> which loads a new vector table specific to that image
<azonenberg_work> whitequark: if you dont have an MMU
<azonenberg_work> the A and B images will be at different addresses
<azonenberg_work> So unless your ISRs are shared by both images
<azonenberg_work> your vector table has to change
<azonenberg_work> you cant just reprogram the start pc/sp in the vector table, you have to rebuild the whole thing
<whitequark> sure you can
<azonenberg_work> i mean you can reprogram those offsets
<azonenberg_work> but then your ISR addresses dont change
<whitequark> just make the firmware set the vector table offset to its own vector table via a pc-relative instruction
<azonenberg_work> Yeah but you need an initial vector table at boot
<azonenberg_work> used by the rom bootloader etc
<whitequark> rom bootloader?
<azonenberg_work> or whaetver state machine in the cpu loads the initial vector table from the start of flash
<azonenberg_work> What i'm saying is, you have one fixed vector table at the start of flash
<azonenberg_work> which you patch to point to image a or b
<azonenberg_work> then those images have their own vector tables
<whitequark> yes, I reprogram pc/sp at offset 0, how's that not enough?
<whitequark> I don't understand what are you referring to
<azonenberg_work> What i meant was, ypi cpi;dm
<azonenberg_work> what i meant was
<azonenberg_work> you couldn't just have one vector table at the start of flash and have that be it
<azonenberg_work> you need a table in each image that you set vtor to
<whitequark> oh yeah sure, why would I have one? that's not even convenient
<azonenberg_work> plus one at the start of flash whose sole purpose is to get patched to point to one image or the other
<whitequark> what if A/B firmwares have different sets of vectors
<azonenberg_work> exactly
<whitequark> ah wait I think I see what you mean
<whitequark> I can't reuse the reset vector pc/sp as the A firmware vector table
<whitequark> s/as/in/
<whitequark> yeah that's mildly annoying
<lain> sacrifice an entire flash erase sector just for your trampoline :V
<azonenberg_work> Weeeellll...
<azonenberg_work> There's some tricks you can do
<whitequark> 16KB erase sectors on this chip... damn
<whitequark> I mean it's still 1MB of flash, but
<lain> yeesh
<azonenberg_work> Some (not all) flash
<azonenberg_work> allows you to do multiple writes to the same addresses
<lain> yeah
<azonenberg_work> and the end resulti s basically the bitwise and of all writes
<azonenberg_work> So you could put one image at say 0x48000 and another at 0x40000
<lain> isn't it the bitwise OR?
<azonenberg_work> 1 -> 0
<azonenberg_work> is the only legal write
<lain> ah right flash is programmed backwards
<azonenberg_work> (unless the flash inverts somewhere)
<azonenberg_work> Anyway, iff your flash allows this
<azonenberg_work> you could clear one bit in the vector table
<lain> yeah, I've used this to implement eeprom emulation on flash to reduce wear
<whitequark> my flash allows this I thin
<azonenberg_work> anyway so what you could do is, have one image start say 16KB after the midpoint of flash
<azonenberg_work> have that be your A image
<azonenberg_work> Second image starts 16KB after the start of flash, that's B
<azonenberg_work> Vector initially points to A
<azonenberg_work> To do an update, you write the new image to the B address
<azonenberg_work> Verify it
<azonenberg_work> then poke the one bit in the pointer
<azonenberg_work> now you're good to go
<azonenberg_work> at some point in the future, before starting another update
<azonenberg_work> you lazily copy the good image from B back to A
<azonenberg_work> then wipe the first sector and rewrite pointing to A
<azonenberg_work> that gives you a small window of a few ms that you could brick on power outage
<azonenberg_work> but makes the main update process atomic
<lain> and if you can characterize that brickable time period you can ensure there's sufficient capacitance to float through it
<azonenberg_work> Correct
<azonenberg_work> it's basically the time to erase one flash sector and rewrite the first few words
<azonenberg_work> Since the remainder of the initial sector is A's vector table
<azonenberg_work> and the initial pc points to B
<azonenberg_work> corruption elsewhere in the table will not brick
<azonenberg_work> so really you have to do an erase and 64-bit write in the brick window
<lain> hm, actually I guess you would have to use a BOD to abort that if it's already low or something now that I think about it... since the power could cut at any point prior to the brick window, with the cap discharge starting /before/ the brick window
<azonenberg_work> Correct
<whitequark> this flash core actually has an integrated BOD
<lain> but that could be as simple as verifying the voltage is sufficiently high (no power loss) just prior to doing it
<lain> oh neat
<azonenberg_work> you'd have to watch vcc and make sure you were good just before starting
<azonenberg_work> then do the atomic operation
<azonenberg_work> but the primary firmware update process need not be fast since the pointer swap *is* atomic
<azonenberg_work> and even a failure halfway through the update that leaves that bit in an undefined state
<azonenberg_work> will result in one of the two images executing :p
azonenberg_work has quit [Ping timeout: 258 seconds]
ZipCPU|Laptop has quit [Ping timeout: 260 seconds]
ZipCPU|Laptop has joined ##openfpga
m_w has joined ##openfpga