Jump to content

davidb

EstablishedMember
  • Content Count

    134
  • Joined

  • Last visited

Posts posted by davidb


  1. Hi,

     

    CPU: AMD FX-8350 8-core 4.00GHz

    Memory: 16GB

    OS: Win7 64-bit Pro

    IDE: MPLAB V8.92

    Compiler: SourceBoost V7.21 Pro

    Target: PIC18F87K22

     

    Not a show stopper but just found that:

     

    The BoostC Compiler -m option does not appear to work when using SourceBoost C under MPLAB. This shows success followed by BUILD FAIL on the first file compiled.

    Works when using SourceBoost IDE.

     

    Perhaps someone else can check this as it may be unique to me.

     

    Regards

     

    davidb

     


  2. Hi mityeltu,

     

    Sorry it didn't work but this is all pretty basic stuff. If your master is not transmitting how do you know that the slave is not working?

     

    It is difficult to comment without seeing your code but have you checked that your basic timing is working? Use a scope and a spare output port for debugging to check the timing and then check that the SPI clock and data outputs from your master are correct. Do this before worrying about the slave.

     

    Regards

     

    davidb


  3. mityeltu,

     

    I would suggest that you thoroughly read the data sheet for the part you are using as well as checking out application notes

    and sample code so that you properly understand how the interrupts work.

     

    It is only my opinion but I believe using delay loops is bad programming practice hence my suggestion of using an interrupt

    driven task timer. You can also use similar techniques to produce one shot timers, PWM etc. Delays are a quick fix for

    simple applications but become a pain when trying to expand the program to do something useful.

     

    While it is generally true that interrupt code should run as quickly as possible it depends on your application. I have

    produced applications where the main () loop has very little code in it with everything being done with interrupts.

     

    What I meant when I said the SPI input is asynchronous is that there will always be a frequency difference and also a varying

    phase between the master and slave clocks. The effect would be that the SPI input occurs at a different point in your slave

    main loop every time. Because of your long delays and depending on the data rate the SPI data buffer could be overwritten

    before you have a chance to read it the first time. This is why you should read the buffer in an interrupt.

     

    I don't think you need to worry too much about dropping a byte since you are using the hardware SPI which has a buffered

    output and you are only transferring one byte at a time at a very slow rate. The interrupt and main code will easily keep up. However, if you

    are worried the 18F452 supports priority level interrupts so put the SPI on a high level interrupt and the timer on a low level interrupt.

    At high data rates you may also need to implement a circular buffer.

     

    Regards

     

    davidb


  4. mityeltu,

     

    Here are a few basic problems, particularly with the slave:

     

    Do not globally disable or re-enable interrupts within the interrupt routine. Doing so is pointless and can cause problems. The global interrupt is

    disabled and re-enabled automatically. In addition why are you disabling pheripheral interrupts within the interrupt?

     

    You are you using the SPI interrupt to set a flag which you then monitor and clear in main (). This is totally pointless, you may as well not use an

    interrupt at all but just monitor the interrupt flag and clear it in main () when required. However, this will not work properly either because you are

    using massive delays in main ().

     

    Don't use in-line delays. These simply waste processor time and are blocking. Depending on the timing this is likely to be the main cause of your

    problem. The SPI input is asynchronous with your slave clock therefore you could easily miss reading an SPI input before another occurs while you

    are stuck in one of your delay loops.

     

    A few basic suggestions for your simply case:

     

    Setup a timer to interrupt regularly, say every 1ms, to give a base frequency. Within this handler decrement a counter and when this reaches

    zero set a flag and reset the count. This flag can then be monitored and cleared in main () to do whatever is required at the right time.
    A number of counters of different sizes and associated flags can be used to produce a range of 'clocks' which can be monitored in main () to carry out different tasks. This method avoids using any long delays and allows the main () code to run as fast as possible.

     

    Use the SPI interrupt but read the input directly within the interrupt. If required a flag could be set to indicate that a new value is available.

    Regards

     

    davidb


  5. Hi,

     

    SourceBoost 7.2 is still broken in regard to comparing signed data types with #defined constants with 18F parts. This is similar to the >= problem that occured in SourceBoost 7.1. which now seems to be fixed.

     

    Problem:

     

    The following test code was created to test for the problem. When compiled for 16F, specifically 16F887, it works fine with 'value' as any data type. When compiled for 18F parts, specifically 18F87K22, it works correctly for a signed char or signed long but fails using a signed short in test case 3.

     

    Expected Behaviour:

     

    To work correctly x should be 1 less than y at the end of the comparison loop for each test case.

     

    IDE: MPLAB V8.89
    Compiler: SourceBoost C V7.2
    Targets: Various 16F, 18F
    Reproducible: 100%
    OS: XP Pro, Vista

    #include <system.h>
    
    static unsigned char x;
    static unsigned char y;
    
    static signed short value;
    static signed short variable_limit = -10;
    
    #define CONSTANT_LIMIT -10
    
    void main()
    {
    	for (;
    	{
    		/* TEST CASE 1 */
    		
    		x = 0;
    		y = 0;
    		
    		for (value = -20; value < 20; value++)
    		{
    			if (value > CONSTANT_LIMIT) // Works O.K.
    			{
    				x++;
    			}
    		  
    			if (value >= CONSTANT_LIMIT) // Works O.K.
    			{
    				y++;
    			}
    		}
    		
    		/* TEST CASE 2 */
    		
    		x = 0;
    		y = 0;
    		
    		for (value = -20; value < 20; value++)
    		{
    			if (value > variable_limit) // Works O.K.
    			{
    				x++;
    			}
    		  
    			if (value >= variable_limit) // Works O.K.
    			{
    				y++;
    			}
    		}
    			
    		/* TEST CASE 3 */
    		
    		x = 0;
    		y = 0;
    		
    		for (value = 20; value > -20; value--)
    		{
    			if (value < CONSTANT_LIMIT) // Works O.K.
    			{
    				x++;
    			}
    			  
    			if (value <= CONSTANT_LIMIT) // Fails with 18F parts
    			{
    				y++;
    			}
    		}
    		
    		/* TEST CASE 4 */
    				
    		x = 0;
    		y = 0;
    			
    		for (value = 20; value > -20; value--)
    		{
    			if (value < variable_limit) // Works O.K.
    			{
    				x++;
    			}
    			  
    			if (value <= variable_limit) // Works O.K.
    			{
    				y++;
    			}
    		}
    	}	
    }
    
    

    Regards

    davidb


  6. Hi,

     

    Not sure if this is related but the following code was extracted from a project and greatly simplified to show the problem with pointers not incrementing using SourceBoost V7.20.

    The structures are normally much larger than these. The comments in the code should explain the problem.

    #include <system.h>
    
    typedef unsigned char uint8_t;
    
    /* A single receive buffer data structure */
    typedef struct _usartRxBuf
    {
    	uint8_t uData[8];
    	uint8_t *pByte;
    } usartRxBuf_t;
    /* USART module data including all buffers and varibles */
    typedef struct _usartData
    {
    	usartRxBuf_t sRxBuf[1];
    	uint8_t      uRxWr;      /* Buffer write index. */
    } sUsartData_t;
    static volatile uint8_t x;
    static volatile sUsartData_t sUsart;	
    void main (void)
    {
    	/* Select buffer to use */	
    	sUsart.uRxWr = 0;	
    	/* Point to start of first buffer */	
    	sUsart.sRxBuf[sUsart.uRxWr].pByte = sUsart.sRxBuf[sUsart.uRxWr].uData;	
    	for (x = 1; x < 9; x++)
    	{
    		/* This should be valid but doesn't work - pointer does not increment
    		* so data is overwritten in the first buffer location
    		* Doesn't work when the buffer array is present (also would normally be sRxBuf[2])
    		* Change the sRxBuf[1] array to just sRxBuf and it works
    		*/			
    		*sUsart.sRxBuf[sUsart.uRxWr].pByte++ = x;
    	}
    	for (x = 1; x < 9; x++)
    	{
    		/* This works - pointer increments correctly */				
    		*sUsart.sRxBuf[sUsart.uRxWr].pByte = x;
    		sUsart.sRxBuf[sUsart.uRxWr].pByte++;
    	}	
    	reset ();
    }
    
    

    Another problem:

     

    The following code from the example above sets the pointer to the start of the array:

    sUsart.sRxBuf[sUsart.uRxWr].pByte = sUsart.sRxBuf[sUsart.uRxWr].uData;

    This compiles O.K. as does:

    sUsart.sRxBuf[sUsart.uRxWr].pByte = (sUsart.sRxBuf[sUsart.uRxWr].uData);

    As does this:

    sUsart.sRxBuf[sUsart.uRxWr].pByte = &sUsart.sRxBuf[sUsart.uRxWr].uData;

    But this fails to compile:

    sUsart.sRxBuf[sUsart.uRxWr].pByte = &(sUsart.sRxBuf[sUsart.uRxWr].uData);

    As far as I can see this is all valid C code and compiles on C18. It appears to be related to the structs since &(ptr) will compile O.K.

     

    Cheers

     

    davidb

     

    SourceBoost V7.20 (Not sure if this was actually released or if it is still RC status)

    Win XP Pro

    PIC18F87K22


  7. Tom,

     

    I can also confirm that the problem exists.

     

    Replacing the defines directly with the values also fails as does various placements of parenthesis and casting to try and break up the problem.

     

    The code seems to break with your values as soon as you have more than 8 OR'ed above 256.

     

    Interestingly if you use enum {} for the values instead of your #defines your example works correctly and as a bonus the code generated is shorter too!

     

    Must be some clues there for Pavel and Dave.

     

    Regards

     

    davidb


  8. Hi

     

    As I see it you are missing a couple of #ifdefs in this code sample.

     

    In fact, in "main", you don't call one of the functions "read_table1/2" depending on your initial #define.

    But the code for both functions with its tables is still part of the program.

    ...

    Best regards

    Jorge

     

    Hi Jorge,

     

    The reason for putting the tables into separate functions was only for test purposes to see the trade offs required between RAM and flash memory usage.

     

    The idea was to simulate the read from the RAM arrays originally used without altering the basic flow of the main code too much. Using conditionals I naively expected that I could select only the required table and the whole function including the table would be removed by the optimizer when the function was unused.

    I had already tried the single function with multiple conditionals as you suggest but, with at least four large 16-bit tables in the real project, it made that function unwieldy, even after forming the tables into blocks. As you say you end up with “#ifdefs” and ”#endifs” everywhere which I find difficult to manage when the code extends over several pages.

     

    The read_table2 () purposely wasn’t called in the sample so that it would be removed during optimization and show that the table inside had remained intact. Check out the program memory after compiling and the 'extra' table will still be there.

     

    Your last idea of using multiple projects using the command line define “–d” is a good one and one I must admit I hadn’t even considered.

     

    The spurious #include "pic18f87k22.h" - Just put that down to cut and paste!

     

    Kind regards

     

    davidb


  9. Dave,

     

    Basic project attached to demonstrate the problem.

     

    Note that in this example the rom definitions in each function are the same but would normally be different and much larger in size. The unused rom read function is apparently removed so I would expect the associated rom definition to be removed as well. However both are still in program memory.

     

    As I said it is not a major problem as I was just experimenting and happened to stumble upon this by accident. My full project now avoids these types of functions anyway

     

    SourceBoost Rom Test.zip.

     

    Regards

     

    davidb


  10. Hi,

     

    I am currently working on some code that is used in a number of similar equipments. These have different 16-bit lookup tables (arrays) in RAM and so I use conditional directives for the different equipments so that the unused arrays get removed.

     

    Because of the array size, no real need for speed and plenty of flash memory I decided to move them into flash using 'rom' lookup tables. For convenience I defined and initialised each 2 x 8-bit 'rom' table within separate functions together with the code to extract and return the 16-bit values. This made it easier to substitute the RAM array read with the ROM table read for testing.

     

    In a way I felt that defining the 'rom' within the function might not be the right thing to do but it seemed to work O.K. However, I was slightly surprised to find that although the conditional compilation correctly removed the unused functions the the 'rom' tables inside them were left behind and therefore used more flash than I was expecting.

     

    I would be interested to know if this effect is by design or just a side effect.

     

    I can get round it without any problem but I thought that it might be useful information to anyone else trying to be clever!

     

    SourceBoost C V7.11

    PIC18F87K22

     

    davidb


  11. Hi,

     

    Just had a quick read of your code and without going too deeply there seem to be a number of problems but to get you over your immediate one try using something like:

     
    
    ...
    unsigned int index = menuButtonScan ();
    
     switch(index){
      case 0:
    ...
    

    instead of simply:

     
    
    ...
     switch(menuButtonScan){
      case 0:
    ...
    

    as this will not work.

     

    You also seem to be calling mainMenu() recursively.

     

    Even if your code eventually does what you want you are using a large number of delays which will block your code from doing anything else useful.

    Sometimes small delays are inevitable but scanning keys, debouncing, driving displays etc. can be done much more effectively and efficiently using simply time slicing for instance.

     

    Good luck!

     

    davidb


  12. Pavel,

     

    As a quick test I simply added the text "// FIXME:" as described by trossin to one of my project files. I can concur that this caused a save file error when trying to compile. This was with BoostC IDE v7.10 on Vista. Interestingly, I couldn't get it to fail when using BoostC IDE on WINXP or from within MPLAB V8.87 on Vista so I am guessing it is a platform related problem. It doesn't seem to be related to the number of files or their size in a project.

     

    Very strange but the obvious fix is to not use the text FIXME!

     

    Hope that helps

     

    davidb


  13. Dan,

     

    I haven't tried this myself but without your full code, the part you are using, clock frequency etc. it is difficult to debug. However, I can see some basic problems.

     

    You are not doing what Microchip AN1298 tells you to do. Read the note, particularly the Sensing Steps section, and try and understand the required sequence of events and what is meant to happen before you attempt to code it.

     

    Where are the port/ADC initialisation, variable definitions etc.?

     

    Where are you switching the ports between ADC input and Digital?

     

    Why do you have massive delays of 20mS? The process needs to be done quickly and anyway long blocking delays will stop you doing anything else useful. The best way to do this is probably to use the ADC interrupt and a simple state machine. This will allow the ADC to run at the fastest rate possible in the background. Depending on the part and clock frequency dummy reads may be required to ensure that the minimum setup time is met.

     

    Your conversion of the 8-bit ADC result registers to 10/16-bit is strange. Simply set the ADC for 10-bit result. Shift adresh up by 8 bits and OR it

    with adresl to get your result as a short. Alternatively use the MAKESHORT macro.

     

    Good luck

     

    davidb


  14. Reynard,

     

    You have commented out the config data which is not a good idea if you are using a 10MHz crystal.

     

    Looks like I missed the most obvious problem! But why comment the config out? The default values - RC Oscillator, LVP on etc. will not work so they must be changed elsewhere.

     

    My suggestion of using a heartbeat would be useful to sort these sort of obvious problems out in the early stages.

     

    davidb


  15. Hi Samith,

     

    You say you are trying to use the virtual power supply which suggests that you are using the SourceBoost IDE and plugins.

     

    I tend to use real hardware with MPLAB and ICD3 or PicKit2/PicKit3, depending on what I am doing, so I am not really the best person to help with simulation problems. There was a bug in the recent release of the simulator for V7.05 but I am not sure if the version for V6.95 worked O.K.

     

    If you can try it on the real hardware then I believe the modified code should work. It looks correct but I haven't tested it so I could have missed something. BTW, you cannot display the 10-bit result on an 8-bit port as you are suggesting!

     

    If you are using real hardware and an external voltage source then be careful how you apply the voltage to the analogue port, it is very easy to damage it by overvolting. This will usually kill the internal protection diode resulting in the ADC reading sticking at some value.

     

    If you are using an external voltage source then use a potential divider/input current limiting resistor. External Schottky clamping diodes (BAT54S) across the rails to the AN input together with the current limiting resistor can provide additional protection.

     

    If you think you may have damaged the port then try another one (change the channel settings as well).

     

    Are you sure that your processor is running? Add a bit of code to flash a heartbeat LED on one of the other port pins just to make sure.

     

    Although there is no reason why the 877 shouldn't work there or more modern and cheaper micros. The PIC16F887 is very similar and even that is getting long in the tooth.

     

    Lastly, there is no need to quote the whole reply everytime, just quote the relevent parts if necessary.

     

    Good luck

     

    davidb

×
×
  • Create New...