From richard at imagecraft.com Wed Apr 2 23:56:41 2008 From: richard at imagecraft.com (Richard Man) Date: Wed Apr 2 23:59:08 2008 Subject: [Icc-430] eBox-AVR, a complete AVR kit Message-ID: <200804030759.m337x66v034939@mail.imagecraft.com> Know anyone starting with embedded design? Know any school that needs a complete embedded kit for their courses? Want to help support ImageCraft? Introducing eBox-AVR, a complete kit with an AVR ATMega16, keypad, LED, LCD and 10 example projects, even comes with a battery. To purchase and look at the amazingly cute yellow top tub it comes in, go to our website www.imagecraft.com, then click on Hardware, then "ImageCraft eBox" button. Thank you. // richard From richard at imagecraft.com Thu Apr 10 03:36:11 2008 From: richard at imagecraft.com (Richard Man) Date: Thu Apr 10 04:38:59 2008 Subject: [Icc-430] V7.07A beta0 Message-ID: <200804101138.m3ABcwgx071713@mail.imagecraft.com> http://www.imagecraft.com/pub/iccv7430_v707a_beta0.exe V7.07A - April 12th, 2008 [ Removed the rarely if ever used RCS interface. Note: ICC no longer uses any GPL utilities. ] IDE - Added Project->Options->Projecti->"Makefile Options" of two choices "Relative Paths" or "Absolute Paths" - HIL.DLL V9.0.xx is used from the NoICE distribution. This seems to solve some rare case of JTAG programming issues. Compiler - Fixed a bug where under some conditions, the use of LPMx macros might cause stack inbalance especially when it is followed by complex floating point expressions. Library - Fixed a bug where strncpy incorrect zeroed out the SRC string if the count argument is shorter than the src string. // richard On-line orders, support, and listservers available on web site. [ For technical support on ImageCraft products, please include all previous replies in your msgs. ] From bailey at peak.org Fri Apr 11 09:34:47 2008 From: bailey at peak.org (bailey@peak.org) Date: Fri Apr 11 10:35:04 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... Message-ID: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> Hi. I'm looking for suggestions of good ways to read the MSP-430 status register from within a function in C as part of an effort to selectively disable/restore the GIE flag. I've played with various approaches: 1) Using inline asm ala: asm("mov r2,%saveSR") This doesn't work since the function it is called from is complex and the compiler apparently can't free up a register to store the local variable saveSR in. 2) Use the "monitor" pragma on the function This doesn't work well since there are multiple sections of code in the function that need protection (chained accesses to the HW multiplier), and turning interrupts off for the duration increases the latency to the point where I'm losing high speed interrupts. 3) Use a simple function to read the value of the SR and return it. This works, but adds more overhead to the function execution than I like. So, anyone have another approach they like, or perhaps a clever way of implementing one of the above? (What I really need is an intrinsic ala IAR, etc :) Cheers, Kirk Bailey Willamette RF, Inc. From jdurand at interstellar.com Fri Apr 11 10:24:38 2008 From: jdurand at interstellar.com (Jerry Durand) Date: Fri Apr 11 11:25:08 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> References: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> Message-ID: <20080411172321.2B7D371E2A0@smtp.interstellar.com> At 09:34 AM 4/11/2008, bailey@peak.org wrote: > Hi. I'm looking for suggestions of good ways to read the MSP-430 >status register from within a function in C as part of an effort to >selectively disable/restore the GIE flag. I've played with various >approaches: > >1) Using inline asm ala: asm("mov r2,%saveSR") > >This doesn't work since the function it is called from is complex and the >compiler apparently can't free up a register to store the local variable >saveSR in. Define a variable in a fixed location of memory and move to that: #pragma abs_address 0x200 unsigned int sr_copy; #pragma end_abs_address asm("mov r2, &0x200"); -- Jerry Durand, Durand Interstellar, Inc. www.interstellar.com tel: +1 408 356-3886, USA toll free: 1 866 356-3886 Skype: jerrydurand -------------- next part -------------- An HTML attachment was scrubbed... URL: http://dragonsgate.net/pipermail/icc-430/attachments/20080411/6ae9d365/attachment.html From bailey at peak.org Fri Apr 11 10:55:54 2008 From: bailey at peak.org (bailey@peak.org) Date: Fri Apr 11 11:56:14 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <20080411172321.2B7D371E2A0@smtp.interstellar.com> References: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> <20080411172321.2B7D371E2A0@smtp.interstellar.com> Message-ID: <1374.69.59.200.77.1207936554.squirrel@webmail.peak.org> Jerry, Thanks for the suggestion. The only problem that I see is that the function in question can be called both from the background and a couple of interrupt routines. Having a single location for the saved status seems destined to lead to a corrupted saved interrupt status when an interrupt (that also calls the function), occurs between when: asm("mov r2, &0x200"); gets executed and the following _DINT(); that disables the interrupts. In the (more), common case where the function only got called from a single thread I think your idea should work. Am I understanding your approach correctly? Kirk Bailey bailey@peak.org > At 09:34 AM 4/11/2008, bailey@peak.org wrote: >> Hi. I'm looking for suggestions of good ways to read the MSP-430 >>status register from within a function in C as part of an effort to >>selectively disable/restore the GIE flag. I've played with various >>approaches: >> >>1) Using inline asm ala: asm("mov r2,%saveSR") >> >>This doesn't work since the function it is called from is complex and the >>compiler apparently can't free up a register to store the local variable >>saveSR in. > > Define a variable in a fixed location of memory and move to that: > > #pragma abs_address 0x200 > unsigned int sr_copy; > #pragma end_abs_address > > asm("mov r2, &0x200"); > > > -- > Jerry Durand, Durand Interstellar, Inc. www.interstellar.com > tel: +1 408 356-3886, USA toll free: 1 866 356-3886 > Skype: jerrydurand > _______________________________________________ > Icc-430 mailing list > Icc-430@imagecraft.com > http://dragonsgate.net/mailman/listinfo/icc-430 > From jdurand at interstellar.com Fri Apr 11 11:11:05 2008 From: jdurand at interstellar.com (Jerry Durand) Date: Fri Apr 11 12:11:29 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1374.69.59.200.77.1207936554.squirrel@webmail.peak.org> References: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> <20080411172321.2B7D371E2A0@smtp.interstellar.com> <1374.69.59.200.77.1207936554.squirrel@webmail.peak.org> Message-ID: <20080411180948.153BE71E41F@smtp.interstellar.com> At 10:55 AM 4/11/2008, bailey@peak.org wrote: >Jerry, > Thanks for the suggestion. The only problem that I see is that the >function in question can be called both from the background and a couple >of interrupt routines. Having a single location for the saved status seems >destined to lead to a corrupted saved interrupt status when an interrupt >(that also calls the function), occurs between when: > >asm("mov r2, &0x200"); > >gets executed and the following _DINT(); that disables the interrupts. Then, use two different saved locations (0x200, 0x202). In the interrupt use a different location. > In the (more), common case where the function only got called from a >single thread I think your idea should work. Am I understanding your >approach correctly? Note that 16 bit moves will NOT be interrupted in the middle. The entire move will happen or not. 32 bit and larger moves CAN be interrupted. If there's a chance of the interrupt changing your data in the middle of a move, disable the interrupt. Be liberal with DINT() and EINT() calls. DINT(); asm("mov r2, &0x200"); new_save = sr_copy; EINT(); I use this all the time when touching long counters used for the time of day or changing settings for something the interrupt is doing. Just don't leave the interrupts off for very long. // global definition ulong RTC; // updated in Salvo tick int Do_Something(void) { ulong time; // local variable DINT(); time = RTC; EINT(); if(time == 42424242L) { return TRUE; } return FALSE; } -- Jerry Durand, Durand Interstellar, Inc. www.interstellar.com tel: +1 408 356-3886, USA toll free: 1 866 356-3886 Skype: jerrydurand From bailey at peak.org Fri Apr 11 11:32:57 2008 From: bailey at peak.org (bailey@peak.org) Date: Fri Apr 11 12:33:13 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <20080411180948.153BE71E41F@smtp.interstellar.com> References: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> <20080411172321.2B7D371E2A0@smtp.interstellar.com> <1374.69.59.200.77.1207936554.squirrel@webmail.peak.org> <20080411180948.153BE71E41F@smtp.interstellar.com> Message-ID: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> Jerry, Now I'm sure I must be missing something. Your suggestion: > DINT(); > asm("mov r2, &0x200"); > new_save = sr_copy; > EINT(); doesn't seem like it would work since the _DINT(); would clear the GIE bit I'm trying to read with the "mov"? And while you can use a _DINT();/ _EINT(); pair to protect critical sections, you had better make sure that interrupts were enabled when the code was called, if not they will be afterwards :) Also, I don't think I can use different addresses to save the status since the address is part of the function being called, not the function doing the calling? If I pass the address in as a parameter then I'm back to the compiler not having an available register to store it in... Kirk > At 10:55 AM 4/11/2008, bailey@peak.org wrote: >>Jerry, >> Thanks for the suggestion. The only problem that I see is that the >>function in question can be called both from the background and a couple >>of interrupt routines. Having a single location for the saved status >> seems >>destined to lead to a corrupted saved interrupt status when an interrupt >>(that also calls the function), occurs between when: >> >>asm("mov r2, &0x200"); >> >>gets executed and the following _DINT(); that disables the interrupts. > > Then, use two different saved locations (0x200, 0x202). In the > interrupt use a different location. > >> In the (more), common case where the function only got called from a >>single thread I think your idea should work. Am I understanding your >>approach correctly? > > Note that 16 bit moves will NOT be interrupted in the middle. The > entire move will happen or not. 32 bit and larger moves CAN be > interrupted. If there's a chance of the interrupt changing your data > in the middle of a move, disable the interrupt. > > Be liberal with DINT() and EINT() calls. > > DINT(); > asm("mov r2, &0x200"); > new_save = sr_copy; > EINT(); > > I use this all the time when touching long counters used for the time > of day or changing settings for something the interrupt is > doing. Just don't leave the interrupts off for very long. > > // global definition > ulong RTC; // updated in Salvo tick > > > int Do_Something(void) { > ulong time; // local variable > > DINT(); > time = RTC; > EINT(); > > if(time == 42424242L) { > return TRUE; > } > > return FALSE; > } > > > -- > Jerry Durand, Durand Interstellar, Inc. www.interstellar.com > tel: +1 408 356-3886, USA toll free: 1 866 356-3886 > Skype: jerrydurand > > _______________________________________________ > Icc-430 mailing list > Icc-430@imagecraft.com > http://dragonsgate.net/mailman/listinfo/icc-430 > From mojaveg at IWVISP.com Fri Apr 11 12:23:33 2008 From: mojaveg at IWVISP.com (mojaveg@IWVISP.com) Date: Fri Apr 11 13:41:15 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> (from bailey@peak.org) (at Fri, 11 Apr 2008 11:32:57 -0700 (PDT)) Message-ID: <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> > Now I'm sure I must be missing something. Your suggestion: > > > DINT(); > > asm("mov r2, &0x200"); > > new_save = sr_copy; > > EINT(); > > doesn't seem like it would work since the _DINT(); would clear the GIE > bit I'm trying to read with the "mov"? And while you can use a _DINT();/ > _EINT(); pair to protect critical sections, you had better make sure that > interrupts were enabled when the code was called, if not they will be > afterwards :) > > Also, I don't think I can use different addresses to save the status > since the address is part of the function being called, not the function > doing the calling? If I pass the address in as a parameter then I'm back > to the compiler not having an available register to store it in... Of what portion of the SR are you trying to make use? What is the obsession about the "compiler not having enough registers to store the result"? Isn't register allocation the compiler's problem? From richard-lists at imagecraft.com Fri Apr 11 13:08:24 2008 From: richard-lists at imagecraft.com (Richard Man) Date: Fri Apr 11 14:11:19 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> References: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> Message-ID: <200804112111.m3BLBJbR012808@mail.imagecraft.com> What's the name and effect of the IAR intrinsic? 1) doesn't work currently only because there's a bug in the asm inline expansion that it doesn't expand non-registered locals correctly. I will fix it. At 09:34 AM 4/11/2008, bailey@peak.org wrote: > Hi. I'm looking for suggestions of good ways to read the MSP-430 >status register from within a function in C as part of an effort to >selectively disable/restore the GIE flag. I've played with various >approaches: > >1) Using inline asm ala: asm("mov r2,%saveSR") > >This doesn't work since the function it is called from is complex and the >compiler apparently can't free up a register to store the local variable >saveSR in. > >2) Use the "monitor" pragma on the function > >This doesn't work well since there are multiple sections of code in the >function that need protection (chained accesses to the HW multiplier), and >turning interrupts off for the duration increases the latency to the point >where I'm losing high speed interrupts. > >3) Use a simple function to read the value of the SR and return it. > >This works, but adds more overhead to the function execution than I like. > > So, anyone have another approach they like, or perhaps a clever way of >implementing one of the above? (What I really need is an intrinsic ala >IAR, etc :) > // richard (This email is for mailing lists. To reach me directly, please use richard at imagecraft.com) From bailey at peak.org Fri Apr 11 18:32:04 2008 From: bailey at peak.org (bailey@peak.org) Date: Fri Apr 11 19:32:21 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <200804112111.m3BLBJbR012808@mail.imagecraft.com> References: <1283.69.59.200.77.1207931687.squirrel@webmail.peak.org> <200804112111.m3BLBJbR012808@mail.imagecraft.com> Message-ID: <1241.69.59.200.77.1207963924.squirrel@webmail.peak.org> Richard et al, IAR provides a couple of ways to access SR. In looking at code around the web that uses the various approaches it looks like implementing the following two intrinsics covers the more common usage, and incidently, functionally matches with the intrinics you already have: unsigned short __get_SR_register(void); Returns the current contents of SR. unsigned short __get_SR_register_on_exit(void); Returns the value SR will be set to on IRQ/monitor function exit. Same idea as the _BIS_SR -vs- _BIS_SR_IRQ difference. In looking at various code examples I couldn't find any popular shorthand names for these critters as macros, but that is definitely less important than providing the functionality! As a "variation", it looks like some folks define the return values to be simple ints. I think they should at least be unsigned, personally. Kirk > What's the name and effect of the IAR intrinsic? > > 1) doesn't work currently only because there's a bug in the asm > inline expansion that it doesn't expand non-registered locals > correctly. I will fix it. > > At 09:34 AM 4/11/2008, bailey@peak.org wrote: >> Hi. I'm looking for suggestions of good ways to read the MSP-430 >>status register from within a function in C as part of an effort to >>selectively disable/restore the GIE flag. I've played with various >>approaches: >> >>1) Using inline asm ala: asm("mov r2,%saveSR") >> >>This doesn't work since the function it is called from is complex and the >>compiler apparently can't free up a register to store the local variable >>saveSR in. >> >>2) Use the "monitor" pragma on the function >> >>This doesn't work well since there are multiple sections of code in the >>function that need protection (chained accesses to the HW multiplier), >> and >>turning interrupts off for the duration increases the latency to the >> point >>where I'm losing high speed interrupts. >> >>3) Use a simple function to read the value of the SR and return it. >> >>This works, but adds more overhead to the function execution than I like. >> >> So, anyone have another approach they like, or perhaps a clever way >> of >>implementing one of the above? (What I really need is an intrinsic ala >>IAR, etc :) >> > > // richard (This email is for mailing lists. To reach me directly, > please use richard at imagecraft.com) > > _______________________________________________ > Icc-430 mailing list > Icc-430@imagecraft.com > http://dragonsgate.net/mailman/listinfo/icc-430 > From bailey at peak.org Fri Apr 11 22:11:16 2008 From: bailey at peak.org (bailey@peak.org) Date: Fri Apr 11 23:11:32 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> (from bailey@peak.org) (at Fri, 11 Apr 2008 11:32:57 -0700 (PDT)) <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> Message-ID: <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> Hi, For the current issue I need to read the GIE bit, but there are other situations where it is useful to be able to examine other status bits. Basically what I'm trying to do is implement two primitives: 1. Enter-Monitor (read current GIE status, set GIE to 0) This primitive is where I need to be able to read the SR, followed by a _DINT() /* or _BIC_SR(GIE) */. Depending on the application it may also be useful to isolate the GIE bit by itself in the saved copy to avoid over-writing some of the other flags in the SR during the later execution of the "exit" primitive. 2. Exit-Monitor (restore saved GIE status) This translates into a _BIS_SR(saved_GIE_status) As far as "my obsession with compiler register allocation", I'm referring to the error message I get from ICC. From Richard's earlier response it sounds like it is a fixable compiler bug, which is encouraging! Kirk .>> Now I'm sure I must be missing something. Your suggestion: >> >> > DINT(); >> > asm("mov r2, &0x200"); >> > new_save = sr_copy; >> > EINT(); >> >> doesn't seem like it would work since the _DINT(); would clear the >> GIE >> bit I'm trying to read with the "mov"? And while you can use a >> _DINT();/ >> _EINT(); pair to protect critical sections, you had better make sure >> that >> interrupts were enabled when the code was called, if not they will be >> afterwards :) >> >> Also, I don't think I can use different addresses to save the status >> since the address is part of the function being called, not the function >> doing the calling? If I pass the address in as a parameter then I'm >> back >> to the compiler not having an available register to store it in... > > Of what portion of the SR are you trying to make use? > > What is the obsession about the "compiler not having > enough registers to store the result"? Isn't register > allocation the compiler's problem? > > > _______________________________________________ > Icc-430 mailing list > Icc-430@imagecraft.com > http://dragonsgate.net/mailman/listinfo/icc-430 > From kris at abbey.co.nz Mon Apr 14 21:42:27 2008 From: kris at abbey.co.nz (Kris Heidenstrom) Date: Mon Apr 14 22:42:51 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> Message-ID: <48043233.6040007@abbey.co.nz> Kirk Bailey (bailey@peak.org) wrote: > For the current issue I need to read the GIE bit, but > there are other situations where it is useful to be > able to examine other status bits. > > Basically what I'm trying to do is implement two > primitives: > > 1. Enter-Monitor (read current GIE status, set GIE to 0) > This primitive is where I need to be able to read the > SR, followed by a _DINT() /* or _BIC_SR(GIE) */. > Depending on the application it may also be useful to > isolate the GIE bit by itself in the saved copy to > avoid over-writing some of the other flags in the SR > during the later execution of the "exit" primitive. > > 2. Exit-Monitor (restore saved GIE status) > This translates into a _BIS_SR(saved_GIE_status) Yes we have the same issue with icc430. It's common in embedded programming to do what you describe. You need to make sure that interrupts are disabled during certain critical sections, but you don't want to lock out interrupts unnecessarily. If your function just enables interrupts explicitly at the end of each critical section, then you have to ensure that the function will never be called in a situation where interrupts are disabled and must stay disabled, because the function will explicitly enable them. This might be a workable approach as long as it's clearly documented and explained. But of course the cleanest solution is the traditional one: push (or otherwise save) the status register explicitly disable interrupts do the critical stuff restore the status register from the saved value. With this method it doesn't matter whether interrupts were disabled on entry to the function or not, because the code never enables them if they weren't already enabled, but only forces interrupts off during critical section(s). We have tried to convince icc430 to do this efficiently by defining an automatic local variable to hold the status register value, and accessing it using asm statements, but it doesn't work because the compiler thinks the local variable has no scope (because it is only accessed from asm statements and the compiler just passes those on to the assembler without looking at them) so the compiler will reuse the register allocated to the local variable for other variables. This was what we tried: void myfunction(void) { auto saved_sr; asm ("mov r2,saved_sr"); /* Save SR */ /* Non-critical code can go here */ asm ("dint"); asm ("nop"); /* (if needed) */ /* Critical code */ asm ("mov saved_sr,r2"); / Restore SR */ /* Non-critical code */ asm ("dint"); asm ("nop"); /* (if needed) */ /* Critical code */ asm ("mov saved_sr,r2"); /* Non-critical code */ /* ... more if wanted ... */ /* Must exit with interrupt flag as on entry */ asm ("mov saved_sr,r2"); /* Non-critical code */ return; } This would be fairly efficient and would have the advantage that you only need to save the status register in the local variable _once_, near the start of the function (which would be an improvement over the common approach of pushing SR onto the stack before _each_ DINT and popping it after the critical section), but we have not been able to get it to work with icc430. At the moment we're using function calls to get and set the status register. This is inefficient, and ironically that inefficiency affects the very code that you want to be as efficient as possible. :-( I would appreciate a formally sanctioned way to deal with this common embedded programming situation. Kris -- Kris Heidenstrom Embedded systems designer / programmer kris@abbey.co.nz Abbey Systems Ltd - Telemetry Specialists Wellington NEW ZEALAND Voice +64-4-385-6611 Fax +64-4-385-6848 From llchisho at paradise.net.nz Mon Apr 14 21:45:03 2008 From: llchisho at paradise.net.nz (llchisho@paradise.net.nz) Date: Mon Apr 14 22:45:25 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... Message-ID: <1208234703.480432cfaa7c6@www.paradise.net.nz> On Fri Apr 11 14:11:19 2008, Richard Man wrote : > 1) doesn't work currently only because there's a bug in the asm > inline expansion that it doesn't expand non-registered locals > correctly. I will fix it. I had noticed this as well - I thought it worked at first but it always returned the same SP offset :-) While somebody is working on this area, is it possible to have the use of a variable via the % mechanism in an asm statement linked to the lifetime of the variable in the same way as using it in a C statement ? This would prevent the compiler from re-using a register or stack location which inline assembly is still using, and would also enable the compiler to correctly assign a register or stack location based on the usage of all the variables. Len Chisholm. From bailey at peak.org Tue Apr 15 00:56:58 2008 From: bailey at peak.org (bailey@peak.org) Date: Tue Apr 15 01:57:19 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <48043233.6040007@abbey.co.nz> References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> <48043233.6040007@abbey.co.nz> Message-ID: <1559.69.59.200.77.1208246218.squirrel@webmail.peak.org> Kris/Len, KRIS, you've got it exactly! I'm keeping my fingers crossed hoping that Richard can find a way to implement the SR access intrinsics: unsigned short __get_SR_register(void); unsigned short __get_SR_register_on_exit(void); With these, the problem yields to a clean and efficient solution. LEN, I also support your desire to get the asm<->C variable access stuff fixed so that when future issues arise we have better tools to tackle them with! Kirk Bailey bailey@peak.org > Kirk Bailey (bailey@peak.org) wrote: > > > For the current issue I need to read the GIE bit, but > > there are other situations where it is useful to be > > able to examine other status bits. > > > > Basically what I'm trying to do is implement two > > primitives: > > > > 1. Enter-Monitor (read current GIE status, set GIE to 0) > > This primitive is where I need to be able to read the > > SR, followed by a _DINT() /* or _BIC_SR(GIE) */. > > Depending on the application it may also be useful to > > isolate the GIE bit by itself in the saved copy to > > avoid over-writing some of the other flags in the SR > > during the later execution of the "exit" primitive. > > > > 2. Exit-Monitor (restore saved GIE status) > > This translates into a _BIS_SR(saved_GIE_status) > > Yes we have the same issue with icc430. It's common in > embedded programming to do what you describe. You need > to make sure that interrupts are disabled during certain > critical sections, but you don't want to lock out > interrupts unnecessarily. > > If your function just enables interrupts explicitly at > the end of each critical section, then you have to ensure > that the function will never be called in a situation > where interrupts are disabled and must stay disabled, > because the function will explicitly enable them. This > might be a workable approach as long as it's clearly > documented and explained. > > But of course the cleanest solution is the traditional one: > > push (or otherwise save) the status register > explicitly disable interrupts > do the critical stuff > restore the status register from the saved value. > > With this method it doesn't matter whether interrupts > were disabled on entry to the function or not, because > the code never enables them if they weren't already > enabled, but only forces interrupts off during critical > section(s). > > We have tried to convince icc430 to do this efficiently > by defining an automatic local variable to hold the status > register value, and accessing it using asm statements, but > it doesn't work because the compiler thinks the local > variable has no scope (because it is only accessed from > asm statements and the compiler just passes those on to > the assembler without looking at them) so the compiler > will reuse the register allocated to the local variable > for other variables. This was what we tried: > > void myfunction(void) { > auto saved_sr; > asm ("mov r2,saved_sr"); /* Save SR */ > /* Non-critical code can go here */ > asm ("dint"); > asm ("nop"); /* (if needed) */ > /* Critical code */ > asm ("mov saved_sr,r2"); / Restore SR */ > /* Non-critical code */ > asm ("dint"); > asm ("nop"); /* (if needed) */ > /* Critical code */ > asm ("mov saved_sr,r2"); > /* Non-critical code */ > /* ... more if wanted ... */ > /* Must exit with interrupt flag as on entry */ > asm ("mov saved_sr,r2"); > /* Non-critical code */ > return; > } > > This would be fairly efficient and would have the > advantage that you only need to save the status register > in the local variable _once_, near the start of the > function (which would be an improvement over the common > approach of pushing SR onto the stack before _each_ DINT > and popping it after the critical section), but we have > not been able to get it to work with icc430. > > At the moment we're using function calls to get and > set the status register. This is inefficient, and > ironically that inefficiency affects the very code > that you want to be as efficient as possible. :-( > > I would appreciate a formally sanctioned way to deal > with this common embedded programming situation. > > Kris > -- > Kris Heidenstrom Embedded systems designer / programmer > kris@abbey.co.nz Abbey Systems Ltd - Telemetry Specialists > Wellington NEW ZEALAND Voice +64-4-385-6611 Fax +64-4-385-6848 > > _______________________________________________ > Icc-430 mailing list > Icc-430@imagecraft.com > http://dragonsgate.net/mailman/listinfo/icc-430 > From richard-lists at imagecraft.com Tue Apr 15 01:02:54 2008 From: richard-lists at imagecraft.com (Richard Man) Date: Tue Apr 15 02:05:43 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1559.69.59.200.77.1208246218.squirrel@webmail.peak.org> References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> <48043233.6040007@abbey.co.nz> <1559.69.59.200.77.1208246218.squirrel@webmail.peak.org> Message-ID: <200804150905.m3F95f0o004456@mail.imagecraft.com> Both features will be implemented. No problem.... (says he...) Just give me a few more days. There;s this minor thing called April 15th (filing extension, as usual) and Embedded System Conference (trying to release Propeller C beta) etc... At 12:56 AM 4/15/2008, bailey@peak.org wrote: >Kris/Len, > > KRIS, you've got it exactly! I'm keeping my fingers crossed hoping >that Richard can find a way to implement the SR access intrinsics: > >unsigned short __get_SR_register(void); >unsigned short __get_SR_register_on_exit(void); > > With these, the problem yields to a clean and efficient solution. > > LEN, I also support your desire to get the asm<->C variable access >stuff fixed so that when future issues arise we have better tools to >tackle them with! > > Kirk Bailey // richard (This email is for mailing lists. To reach me directly, please use richard at imagecraft.com) From t.jaspers at cpseurope.com Tue Apr 15 03:54:08 2008 From: t.jaspers at cpseurope.com (Jaspers, Ton) Date: Tue Apr 15 04:54:31 2008 Subject: [Icc-430] April 15th In-Reply-To: <200804150905.m3F95f0o004456@mail.imagecraft.com> Message-ID: <7B0EB27CF1CC93439B5CFB7526E5D74C5E01F0@mickey.PBNV.local> > -----Original Message----- > From: Richard Man > > Just give me a few more days. There;s this minor thing called > April 15th (filing extension, as usual) On behalf of all of us I wish you high taxes! Ton From aek at pumpkininc.com Tue Apr 15 09:41:30 2008 From: aek at pumpkininc.com (Andrew Kalman) Date: Tue Apr 15 10:42:47 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1559.69.59.200.77.1208246218.squirrel@webmail.peak.org> References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> <48043233.6040007@abbey.co.nz> <1559.69.59.200.77.1208246218.squirrel@webmail.peak.org> Message-ID: In IAR EW430, Salvo 4 uses: static istate_t s; void OSDisableHook(void) { s = __get_interrupt_state(); __disable_interrupt()' } void OSEnableHook(void) { __set_interrupt_state(s); } Works for all situations (including functions called from ISR). --Andrew >Kris/Len, > > KRIS, you've got it exactly! I'm keeping my fingers crossed hoping >that Richard can find a way to implement the SR access intrinsics: > >unsigned short __get_SR_register(void); >unsigned short __get_SR_register_on_exit(void); > > With these, the problem yields to a clean and efficient solution. > > LEN, I also support your desire to get the asm<->C variable access >stuff fixed so that when future issues arise we have better tools to >tackle them with! > > Kirk Bailey > bailey@peak.org > >> Kirk Bailey (bailey@peak.org) wrote: >> >> > For the current issue I need to read the GIE bit, but >> > there are other situations where it is useful to be >> > able to examine other status bits. >> > >> > Basically what I'm trying to do is implement two >> > primitives: >> > >> > 1. Enter-Monitor (read current GIE status, set GIE to 0) >> > This primitive is where I need to be able to read the >> > SR, followed by a _DINT() /* or _BIC_SR(GIE) */. >> > Depending on the application it may also be useful to >> > isolate the GIE bit by itself in the saved copy to >> > avoid over-writing some of the other flags in the SR >> > during the later execution of the "exit" primitive. >> > >> > 2. Exit-Monitor (restore saved GIE status) >> > This translates into a _BIS_SR(saved_GIE_status) >> >> Yes we have the same issue with icc430. It's common in >> embedded programming to do what you describe. You need >> to make sure that interrupts are disabled during certain >> critical sections, but you don't want to lock out >> interrupts unnecessarily. >> >> If your function just enables interrupts explicitly at >> the end of each critical section, then you have to ensure >> that the function will never be called in a situation >> where interrupts are disabled and must stay disabled, >> because the function will explicitly enable them. This >> might be a workable approach as long as it's clearly >> documented and explained. >> >> But of course the cleanest solution is the traditional one: >> >> push (or otherwise save) the status register >> explicitly disable interrupts >> do the critical stuff >> restore the status register from the saved value. >> >> With this method it doesn't matter whether interrupts >> were disabled on entry to the function or not, because >> the code never enables them if they weren't already >> enabled, but only forces interrupts off during critical >> section(s). >> >> We have tried to convince icc430 to do this efficiently >> by defining an automatic local variable to hold the status >> register value, and accessing it using asm statements, but >> it doesn't work because the compiler thinks the local >> variable has no scope (because it is only accessed from >> asm statements and the compiler just passes those on to >> the assembler without looking at them) so the compiler >> will reuse the register allocated to the local variable >> for other variables. This was what we tried: >> >> void myfunction(void) { >> auto saved_sr; >> asm ("mov r2,saved_sr"); /* Save SR */ >> /* Non-critical code can go here */ >> asm ("dint"); >> asm ("nop"); /* (if needed) */ >> /* Critical code */ >> asm ("mov saved_sr,r2"); / Restore SR */ >> /* Non-critical code */ >> asm ("dint"); >> asm ("nop"); /* (if needed) */ >> /* Critical code */ >> asm ("mov saved_sr,r2"); >> /* Non-critical code */ >> /* ... more if wanted ... */ >> /* Must exit with interrupt flag as on entry */ >> asm ("mov saved_sr,r2"); >> /* Non-critical code */ >> return; >> } >> >> This would be fairly efficient and would have the >> advantage that you only need to save the status register >> in the local variable _once_, near the start of the > > function (which would be an improvement over the common >> approach of pushing SR onto the stack before _each_ DINT >> and popping it after the critical section), but we have >> not been able to get it to work with icc430. >> >> At the moment we're using function calls to get and >> set the status register. This is inefficient, and >> ironically that inefficiency affects the very code >> that you want to be as efficient as possible. :-( >> >> I would appreciate a formally sanctioned way to deal >> with this common embedded programming situation. >> >> Kris >> -- >> Kris Heidenstrom Embedded systems designer / programmer >> kris@abbey.co.nz Abbey Systems Ltd - Telemetry Specialists >> Wellington NEW ZEALAND Voice +64-4-385-6611 Fax +64-4-385-6848 >> >> _______________________________________________ >> Icc-430 mailing list >> Icc-430@imagecraft.com >> http://dragonsgate.net/mailman/listinfo/icc-430 >> > > >_______________________________________________ >Icc-430 mailing list >Icc-430@imagecraft.com >http://dragonsgate.net/mailman/listinfo/icc-430 -- ______________________________________ Andrew E. Kalman, Ph.D. aek@pumpkininc.com From bailey at peak.org Tue Apr 15 11:25:31 2008 From: bailey at peak.org (bailey@peak.org) Date: Tue Apr 15 12:25:54 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> <48043233.6040007@abbey.co.nz> <1559.69.59.200.77.1208246218.squirrel@webmail.peak.org> Message-ID: <1059.69.59.200.77.1208283931.squirrel@webmail.peak.org> If Richard wants to add "__get_interrupt_state"/"__set_interrupt_state" to the list I would support it. Relative to "__get_SR_registerX", "__get_interrupt_state" has the shortcoming that (as I understand it anyway), it is only "documented" to return the interrupt enable state, not the rest of the 430 status bits (useful stuff like the CPU flags, LPM state, etc.) On the pro side, by abstracting only the interrupt enable aspect, it is more portable to non-430 stuff (thus likely the use by Salvo which needs to run on more than the 430...) In an ideal world it would be nice to have both: If I can only have one, I want the full SR contents! Kirk Bailey > In IAR EW430, Salvo 4 uses: > > static istate_t s; > > void OSDisableHook(void) > { > s = __get_interrupt_state(); > __disable_interrupt()' > } > > void OSEnableHook(void) > { > __set_interrupt_state(s); > } > > Works for all situations (including functions called from ISR). > > --Andrew > > >>Kris/Len, >> >> KRIS, you've got it exactly! I'm keeping my fingers crossed hoping >>that Richard can find a way to implement the SR access intrinsics: >> >>unsigned short __get_SR_register(void); >>unsigned short __get_SR_register_on_exit(void); >> >> With these, the problem yields to a clean and efficient solution. >> >> LEN, I also support your desire to get the asm<->C variable access >>stuff fixed so that when future issues arise we have better tools to >>tackle them with! >> >> Kirk Bailey >> bailey@peak.org >> >>> Kirk Bailey (bailey@peak.org) wrote: >>> >>> > For the current issue I need to read the GIE bit, but >>> > there are other situations where it is useful to be >>> > able to examine other status bits. >>> > >>> > Basically what I'm trying to do is implement two >>> > primitives: >>> > >>> > 1. Enter-Monitor (read current GIE status, set GIE to 0) >>> > This primitive is where I need to be able to read the >>> > SR, followed by a _DINT() /* or _BIC_SR(GIE) */. >>> > Depending on the application it may also be useful to >>> > isolate the GIE bit by itself in the saved copy to >>> > avoid over-writing some of the other flags in the SR >>> > during the later execution of the "exit" primitive. >>> > >>> > 2. Exit-Monitor (restore saved GIE status) >>> > This translates into a _BIS_SR(saved_GIE_status) >>> >>> Yes we have the same issue with icc430. It's common in >>> embedded programming to do what you describe. You need >>> to make sure that interrupts are disabled during certain >>> critical sections, but you don't want to lock out >>> interrupts unnecessarily. >>> >>> If your function just enables interrupts explicitly at >>> the end of each critical section, then you have to ensure >>> that the function will never be called in a situation >>> where interrupts are disabled and must stay disabled, >>> because the function will explicitly enable them. This >>> might be a workable approach as long as it's clearly >>> documented and explained. >>> >>> But of course the cleanest solution is the traditional one: >>> >>> push (or otherwise save) the status register >>> explicitly disable interrupts >>> do the critical stuff >>> restore the status register from the saved value. >>> >>> With this method it doesn't matter whether interrupts >>> were disabled on entry to the function or not, because >>> the code never enables them if they weren't already >>> enabled, but only forces interrupts off during critical >>> section(s). >>> >>> We have tried to convince icc430 to do this efficiently >>> by defining an automatic local variable to hold the status >>> register value, and accessing it using asm statements, but >>> it doesn't work because the compiler thinks the local >>> variable has no scope (because it is only accessed from >>> asm statements and the compiler just passes those on to >>> the assembler without looking at them) so the compiler >>> will reuse the register allocated to the local variable >>> for other variables. This was what we tried: >>> >>> void myfunction(void) { >>> auto saved_sr; >>> asm ("mov r2,saved_sr"); /* Save SR */ >>> /* Non-critical code can go here */ >>> asm ("dint"); >>> asm ("nop"); /* (if needed) */ >>> /* Critical code */ >>> asm ("mov saved_sr,r2"); / Restore SR */ >>> /* Non-critical code */ >>> asm ("dint"); >>> asm ("nop"); /* (if needed) */ >>> /* Critical code */ >>> asm ("mov saved_sr,r2"); >>> /* Non-critical code */ >>> /* ... more if wanted ... */ >>> /* Must exit with interrupt flag as on entry */ >>> asm ("mov saved_sr,r2"); >>> /* Non-critical code */ >>> return; >>> } >>> >>> This would be fairly efficient and would have the >>> advantage that you only need to save the status register >>> in the local variable _once_, near the start of the >> > function (which would be an improvement over the common >>> approach of pushing SR onto the stack before _each_ DINT >>> and popping it after the critical section), but we have >>> not been able to get it to work with icc430. >>> >>> At the moment we're using function calls to get and >>> set the status register. This is inefficient, and >>> ironically that inefficiency affects the very code >>> that you want to be as efficient as possible. :-( >>> >>> I would appreciate a formally sanctioned way to deal >>> with this common embedded programming situation. >>> >>> Kris >>> -- >>> Kris Heidenstrom Embedded systems designer / programmer >>> kris@abbey.co.nz Abbey Systems Ltd - Telemetry Specialists >>> Wellington NEW ZEALAND Voice +64-4-385-6611 Fax +64-4-385-6848 >>> >>> _______________________________________________ >>> Icc-430 mailing list >>> Icc-430@imagecraft.com >>> http://dragonsgate.net/mailman/listinfo/icc-430 >>> >> >> >>_______________________________________________ >>Icc-430 mailing list >>Icc-430@imagecraft.com >>http://dragonsgate.net/mailman/listinfo/icc-430 > > > -- > ______________________________________ > Andrew E. Kalman, Ph.D. aek@pumpkininc.com > > _______________________________________________ > Icc-430 mailing list > Icc-430@imagecraft.com > http://dragonsgate.net/mailman/listinfo/icc-430 > From kris at abbey.co.nz Tue Apr 15 14:47:38 2008 From: kris at abbey.co.nz (Kris Heidenstrom) Date: Tue Apr 15 15:48:09 2008 Subject: [Icc-430] Reading MSP-430 status register from C.... In-Reply-To: <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> References: <1649.69.59.200.77.1207938777.squirrel@webmail.peak.org> <38f30b30.u10t12e.5161d-mojaveg@67-150-174-174.lsan.mdsg-pacwest.com> <1266.69.59.200.77.1207977076.squirrel@webmail.peak.org> Message-ID: <4805227A.8060208@abbey.co.nz> Kirk Bailey (bailey@peak.org) wrote: > For the current issue I need to read the GIE bit, but > there are other situations where it is useful to be > able to examine other status bits. > > Basically what I'm trying to do is implement two > primitives: > > 1. Enter-Monitor (read current GIE status, set GIE > to 0) > This primitive is where I need to be able to read the > SR, followed by a _DINT() /* or _BIC_SR(GIE) */. > Depending on the application it may also be useful to > isolate the GIE bit by itself in the saved copy to > avoid over-writing some of the other flags in the SR > during the later execution of the "exit" primitive. > > 2. Exit-Monitor (restore saved GIE status) > This translates into a _BIS_SR(saved_GIE_status) Yes we have the same issue with icc430. It's common in embedded programming to do exactly what you describe. You need to make sure that interrupts are disabled during certain critical sections, but you don't want to lock out interrupts unnecessarily. If your function just enables interrupts explicitly at the end of each critical section, then you have to ensure that the function will never be called in a situation where interrupts are disabled and must stay disabled, because the function will explicitly enable them. This might be a workable approach as long as it's clearly documented and explained. But of course the cleanest solution is the traditional one: push (or otherwise save) the status register explicitly disable interrupts do the critical stuff restore the status register from the saved value. With this approach it doesn't matter whether interrupts were disabled on entry to the function or not, because the code never enables them if they weren't already enabled, but only forces interrupts off during critical section(s). We have tried to convince icc430 to do this efficiently by defining an automatic local variable to hold the status register value, and accessing it using asm statements, but it doesn't work because the compiler thinks the local variable has no scope (because it is only accessed from asm statements and the compiler just passes those on to the assembler without looking at them) so the compiler will reuse the register allocated to the local variable for other variables. This was the general idea: void myfunction(void) { auto saved_sr; asm ("mov r2,saved_sr"); /* Save SR */ /* Non-critical code can go here */ asm ("dint"); asm ("nop"); /* (if needed) */ /* Critical code */ asm ("mov saved_sr,r2"); / Restore SR */ /* Non-critical code */ asm ("dint"); asm ("nop"); /* (if needed) */ /* Critical code */ asm ("mov saved_sr,r2"); /* Non-critical code */ /* ... more if wanted ... */ /* Must exit with interrupt flag as on entry */ asm ("mov saved_sr,r2"); /* Non-critical code */ return; } This would be fairly efficient and would have the advantage that you only need to save the status register in the local variable _once_, near the start of the function (which would be an improvement over the common approach of pushing SR onto the stack before _each_ DINT and popping it to restore the interrupt flag), but we haven't been able to make it work. At the moment we're using function calls to get and set the status register. This is inefficient, and ironically that inefficiency affects the very code that you want to be as efficient as possible. :-( I would appreciate a formally sanctioned way to deal with this common embedded programming situation. Kris -- Kris Heidenstrom Embedded systems designer / programmer kris@abbey.co.nz Abbey Systems Ltd - Telemetry Specialists Wellington NEW ZEALAND Voice +64-4-385-6611 Fax +64-4-385-6848 From llchisho at paradise.net.nz Tue Apr 15 15:59:53 2008 From: llchisho at paradise.net.nz (llchisho@paradise.net.nz) Date: Tue Apr 15 17:00:16 2008 Subject: [Icc-430] Installation of beta versions Message-ID: <1208300393.48053369b4e99@www.paradise.net.nz> Hi all, Currently I have 3 versions of icc430 installed on my PC : V6.08 - for bug-fixing of products in the field V7.06A - approved for current production code builds V7.07 beta - for looking to see what has been changed since last time :-) These are all in separate directories. Last time I un-installed a beta, I found that the icc430 registry entries had all been cleaned out and I had to reconfigure my production environment (window size and position, NoIce, etc). These are in HKCU\Software\ImageCraft\ICCV7 for 430. There is only one entry in the Add/Remove programs list for V7 as well, and it disappears if a beta is uninstalled. I've just uninstalled beta 1 and it has indeed killed my V7.06A settings, although no vital code seems to have gone from shared folders. I see that V6 has a different tag in Add/Remove programs, and it seems to have retained its registry settings as well in HKCU\Software\ImageCraft\ICC430. Is is possible to package each beta (at the least, maybe also each major release) to use a different tag in Add/Remove programs, and if they can't have their own configuration in the registry, at least not kill the existing entries on removal ? Perhaps the uninstaller can optionally not remove the registry stuff if that's easier. I know that people playing with betas should expect some extra work but they shouldn't damage other versions. Len Chisholm. From bgarmer at ambientalert.com Thu Apr 24 14:46:52 2008 From: bgarmer at ambientalert.com (Bill Garmer) Date: Thu Apr 24 15:47:26 2008 Subject: [Icc-430] Assembly Module Message-ID: <94C5A1526E432B469C9E047B917B0D9714F7FB@ACSDC1.ambient.corp> Is there an include file I should be using in an assembly module to define the register names? It is a bear to have to type in the address each time. From bgarmer at ambientalert.com Fri Apr 25 11:04:07 2008 From: bgarmer at ambientalert.com (Bill Garmer) Date: Fri Apr 25 12:04:42 2008 Subject: [Icc-430] RE: Contents of Icc-430 Digest, Vol 40, Issue 7 In-Reply-To: <200804251900.m3PJ01G9060008@mail.imagecraft.com> Message-ID: <94C5A1526E432B469C9E047B917B0D9714F801@ACSDC1.ambient.corp> Richard from ImageCraft already got back to me that there is no such include file in the package. Anyone rolled their own?