Thread: [Flashforth-devel] more fun with PIC18F46K22-s...
Brought to you by:
oh2aun
From: craig b. <dab...@ya...> - 2019-12-08 19:33:27
|
Maybe this is a bit ambitious, but I’m trying to build a temperature controller in a Pic18F46K22 involving the console (uart1), a network slave comm (uart2), an oled character display (spi1), and an external ADC (spi-bit-bang). The PWMs and ADC reads are controlled from 4 programmable soft timers through user-interrupt using timer4 rolling over each millisecond (I’ld have daisy-chained the sys-tick but haven’t put a hook into the kernel for that). The networking comm has sparse activity, so I just use a buffered Rc2 in the user-interrupt to accumulate the small packets and process at leisure. The display drive is blocking, but only used for a few characters at a time when the primary heat drive is active, so I’m not worried about that (yet). I’ve run into what look like timing conflicts since activating the Tx2 response drive. The blocking output approach will over-run the millisecond boundaries of my timer checking. Buffering the output packet and using a user-interrupt trigger to send each character has been dropping bytes for no readily apparent reason. Most annoying, the timing behavior problems are still there. I’ve never worked with multi-tasking in 8-bit processors so I’m a little unclear as to what tasks are supposed to do and how to launch and handle them. Is it possible and practical to launch a packet-send task from inside an interrupt and have it execute outside while being interrupted when timing required it? Does it make sense to try? A somewhat more detailed walk-through of Task Setup would be much appreciated by this dinosaur who predates structured programming (grin). Point of curiosity: Has buffered uart transmission now been permanently dropped from FlashForth? I went back to an older source version and enabled it as an experiment and the first thing I noticed was that the warm-start greeting line routinely lost a character (although not always the same one). The output line is longer than the buffer size when the buffer is set to 32 (documented as max without tweaking the linker file (what needs changed?)). Is an unhandled buffer overflow problem why it doesn’t appear as an option anymore? OBTW: a couple of #ifdef-s in the WARM_: uart setup code appear to have gotten lost and need to be added back in for compiling to use UART2 as CONSOLE. I stumbled into that while grasping at straws and then found that compiling it gave a console baudrate that TerraTerm can’t match up with. I found that only half of spbrgvalx4 was getting loaded into SPBRG2 but once fixed, there appears to be no console input at all... There are only so many problems I can look into with only weekends available to chase my obsessions (grin). I’m still fighting with GitHub, so I won’t try to publish a branch and throw a pull request, but here’s what I’ve got so far on the UART2 problem: #else ; UART == 2 --------------------------------------- #ifdef BRG16 bsf BAUDCON2, BRG16 ; movlw spbrgvalx4 movlw high(spbrgvalx4) movwf SPBRGH2, BANKED movlw low(spbrgvalx4) #else movlw spbrgval #endif movwf SPBRG2, BANKED ; TX enable movlw b'00100100' movwf TXSTA2, BANKED ; RX enable movlw b'10010000' movwf RCSTA2, BANKED bsf PIE3, RC2IE #ifdef ANSEL18 #ifdef ANCON2 bcf ANCON2, ANSEL18, BANKED ; Enable digital RG2 for RX2 (18F87K22 family) #endif ; Other values may be needed depending on chip #endif #endif #else ; K42 K83 #if UART == 1 ; ---------------------------------------------- Thanks for your attention, craig bair -- still trying not to remember DEC-FORTRAN and MACRO-11... |
From: Mikael N. <mik...@fl...> - 2019-12-08 22:19:15
|
I am not sure I fully understand what you are doing, but... You can put the UART2 stuff in a background task. : uart2rx-loop init begin rx2 processchar again ; : uart2tx-loop init begin On 2019-12-08 21:33, craig bair via Flashforth-devel wrote: > Maybe this is a bit ambitious, but I’m trying to build a temperature > controller in a Pic18F46K22 involving the console (uart1), a network > slave comm (uart2), an oled character display (spi1), and an external > ADC (spi-bit-bang). The PWMs and ADC reads are controlled from 4 > programmable soft timers through user-interrupt using timer4 rolling > over each millisecond (I’ld have daisy-chained the sys-tick but > haven’t put a hook into the kernel for that). The networking comm has > sparse activity, so I just use a buffered Rc2 in the user-interrupt to > accumulate the small packets and process at leisure. The display > drive is blocking, but only used for a few characters at a time when > the primary heat drive is active, so I’m not worried about that (yet). > I’ve run into what look like timing conflicts since activating the > Tx2 response drive. The blocking output approach will over-run the > millisecond boundaries of my timer checking. Buffering the output > packet and using a user-interrupt trigger to send each character has > been dropping bytes for no readily apparent reason. Most annoying, the > timing behavior problems are still there. > > I’ve never worked with multi-tasking in 8-bit processors so I’m a > little unclear as to what tasks are supposed to do and how to launch > and handle them. Is it possible and practical to launch a packet-send > task from inside an interrupt and have it execute outside while being > interrupted when timing required it? Does it make sense to try? A > somewhat more detailed walk-through of Task Setup would be much > appreciated by this dinosaur who predates structured programming > (grin). > Point of curiosity: Has buffered uart transmission now been > permanently dropped from FlashForth? I went back to an older source > version and enabled it as an experiment and the first thing I noticed > was that the warm-start greeting line routinely lost a character > (although not always the same one). The output line is longer than > the buffer size when the buffer is set to 32 (documented as max > without tweaking the linker file (what needs changed?)). Is an > unhandled buffer overflow problem why it doesn’t appear as an option > anymore? > > OBTW: a couple of #ifdef-s in the WARM_: uart setup code appear to > have gotten lost and need to be added back in for compiling to use > UART2 as CONSOLE. I stumbled into that while grasping at straws and > then found that compiling it gave a console baudrate that TerraTerm > can’t match up with. I found that only half of spbrgvalx4 was > getting loaded into SPBRG2 but once fixed, there appears to be no > console input at all... There are only so many problems I can look > into with only weekends available to chase my obsessions (grin). > > I’m still fighting with GitHub, so I won’t try to publish a branch and > throw a pull request, but here’s what I’ve got so far on the UART2 > problem: > > > #else ; UART == 2 --------------------------------------- > #ifdef BRG16 > bsf BAUDCON2, BRG16 > ; movlw spbrgvalx4 > movlw high(spbrgvalx4) > movwf SPBRGH2, BANKED > movlw low(spbrgvalx4) > #else > movlw spbrgval > #endif > movwf SPBRG2, BANKED > ; TX enable > movlw b'00100100' > movwf TXSTA2, BANKED > ; RX enable > movlw b'10010000' > movwf RCSTA2, BANKED > bsf PIE3, RC2IE > #ifdef ANSEL18 > #ifdef ANCON2 > bcf ANCON2, ANSEL18, BANKED ; Enable digital RG2 for RX2 > (18F87K22 family) > #endif ; Other values may be needed > depending on chip > #endif > #endif > #else ; K42 K83 > #if UART == 1 ; ---------------------------------------------- > > Thanks for your attention, > craig bair -- still trying not to remember DEC-FORTRAN and MACRO-11... > > > > _______________________________________________ > Flashforth-devel mailing list > Fla...@li... > https://lists.sourceforge.net/lists/listinfo/flashforth-devel -- -- Mikael |
From: Mikael N. <mik...@fl...> - 2019-12-08 22:44:01
|
I am not sure I fully understand what you are doing, but... I hope you are running at full clock speed. To get more capacity I would use HW timers for the ADC and PWM. That saves many cycles. Remember that your user interrupt routine is checked at every interrupt. Except in the latest FlashForths. There the system tick will not check the user interrupt. You can put the UART2 stuff in two background tasks. Something like this. I assume RX2 and TX2 calls PAUSE if they would block. 0 30 30 0 task: rx2.task : rx2.loop init.rx2 begin rx2 processchar again ; 0 30 30 0 task: tx2.task : tx2.loop init.tx2 begin get.char.from.tx2.memory.queue tx2 again ; : main init.uart2 ['] rx2.loop rx2.task tinit rx2.task run ['] tx2.loop tx2.task tinit tx2.task run begin bla.bla pause put.char.to.tx2.memory.queue again ; Mikael |
From: craig b. <dab...@ya...> - 2019-12-09 14:42:57
|
Mikael, Thanks much! I'll see if I can get these suggestions to work for me this next weekend. I didn't know that the user interrupts might not be getting serviced, I may try setting up some vectors in eeprom and hook the main interrupt service to check them if they're set to something valid. I've extended the sys-tick to 32 bits and added a word "dticks" to toss the double onto the stack when needed. I've looked back into the Buffered TX code and still don't see the hole that the character is leaking out of when the output string exceeds the buffer size, but since I'm going to use output packets of less than 32 bytes for my TX2 it might work to roll a custom version back into the kernal. It looks like you were using the linker to align all of the buffers on 16 byte boundries back then. Do the "**_FULL_BIT" macros rely on that? (I never used linker scripts, I just hard-positioned my variables in the *.asm (grin)). Oh, and yes, I'm pushing the chip to 64mhz. I haven't tried overclocking yet. Thanks Again! (and keep smiling), craig On Sunday, December 8, 2019, 5:44:10 PM EST, Mikael Nordman <mik...@fl...> wrote: I am not sure I fully understand what you are doing, but... I hope you are running at full clock speed. To get more capacity I would use HW timers for the ADC and PWM. That saves many cycles. Remember that your user interrupt routine is checked at every interrupt. Except in the latest FlashForths. There the system tick will not check the user interrupt. You can put the UART2 stuff in two background tasks. Something like this. I assume RX2 and TX2 calls PAUSE if they would block. 0 30 30 0 task: rx2.task : rx2.loop init.rx2 begin rx2 processchar again ; 0 30 30 0 task: tx2.task : tx2.loop init.tx2 begin get.char.from.tx2.memory.queue tx2 again ; : main init.uart2 ['] rx2.loop rx2.task tinit rx2.task run ['] tx2.loop tx2.task tinit tx2.task run begin bla.bla pause put.char.to.tx2.memory.queue again ; Mikael _______________________________________________ Flashforth-devel mailing list Fla...@li... https://lists.sourceforge.net/lists/listinfo/flashforth-devel |
From: Mikael N. <mik...@fl...> - 2019-12-10 07:44:47
|
Hi Craig. In fact all interrupts are serviced. My point was just that it takes clock cycles when on the PIC18 you need to scan all potential interrupt flags even if only one flag is set. To optimize that a little bit the system tick code does a RETFIE without checking any further interrupts. These will then be serviced immediately afterwards when the interrupt code is called again. Another tip is the use a lower system tick resolution. It will reduce the load a little bit. You can configure the system tick time in the latest FFs. Do you really need a 1 ms resolution ? The buffers do not need to be aligned, but the size needs to be a power of 2. The _FULL_BIT macros are checking the fill level counter. You can use TMR2 to control the HW PWM frequency. I suppose the A/D can just be polled whenever, as long as it is often enough. I removed the buffered TX because I never used it. And I never heard of anyone using it either. But I have never pushed the PICs to the limit. Just using soft realtime :-) BR Mikael On 2019-12-09 16:31, craig bair via Flashforth-devel wrote: > Mikael, > Thanks much! I'll see if I can get these suggestions to work for me this next weekend. > > I didn't know that the user interrupts might not be getting serviced, I may try setting up some vectors in eeprom and hook the main interrupt service to check them if they're set to something valid. I've extended the sys-tick to 32 bits and added a word "dticks" to toss the double onto the stack when needed. > > I've looked back into the Buffered TX code and still don't see the hole that the character is leaking out of when the output string exceeds the buffer size, but since I'm going to use output packets of less than 32 bytes for my TX2 it might work to roll a custom version back into the kernal. It looks like you were using the linker to align all of the buffers on 16 byte boundries back then. Do the "**_FULL_BIT" macros rely on that? (I never used linker scripts, I just hard-positioned my variables in the *.asm (grin)). > > Oh, and yes, I'm pushing the chip to 64mhz. I haven't tried overclocking yet. > > Thanks Again! (and keep smiling), > craig |
From: Tristan W. <ho...@tj...> - 2019-12-11 06:26:35
|
Hello, I would like to measure the width of some pulses using FlashForth on a PIC18F14K50. My first thought was to do this using the capture mode of the ECCP unit - setting it to look for a rising edge then switch to look for a falling edge in an interrupt routine. I have a working interrupt routine which is seems to be serviced every millisecond (driven from the 1ms timer1/ticks in my p18-main.cfg?). However, the pulses I wish to measure are only a few hundred microseconds in length. Is there a way to increase the frequency of servicing of my interrupt routine or another way to approach this? Kind regards and thanks, Tristan |
From: Mikael N. <mik...@fl...> - 2019-12-11 06:48:20
|
Tristan, The best solution is to let the rising edge triggered interrupt switch to falling edge mode, and to start a timer counting clock cycles. Then in the falling edge interrupt routine you can just stop the counter and read out the value from the timer to get the pulse width. Then zero the counter and switch to rising edge mode. Mikael On 2019-12-11 08:26, Tristan Williams wrote: > Hello, > > I would like to measure the width of some pulses using FlashForth on a > PIC18F14K50. My first thought was to do this using the capture mode of > the ECCP unit - setting it to look for a rising edge then switch to > look for a falling edge in an interrupt routine. I have a working > interrupt routine which is seems to be serviced every millisecond > (driven from the 1ms timer1/ticks in my p18-main.cfg?). However, the > pulses I wish to measure are only a few hundred microseconds in length. > > Is there a way to increase the frequency of servicing of my interrupt > routine or another way to approach this? > > Kind regards and thanks, > Tristan > > > _______________________________________________ > Flashforth-devel mailing list > Fla...@li... > https://lists.sourceforge.net/lists/listinfo/flashforth-devel -- -- Mikael |