Jump to content


  • Posts

  • Joined

  • Last visited

Profile Information

  • Location
    Essex, UK

davidb's Achievements


Enthusiast (3/6)



  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. Bade, Use the required library files from the 'SourceBoost\Lib\large' folder rather than those in the 'SourceBoost\Lib' folder. Unfortunately the documentation for the use of the various library files seems to be somewhat lacking. Regards davidb
  3. Bade, The error message tells you that the Linker needs the -idx2 option as well! Also, probably wise to upgrade to V7.21. Regards davidb
  4. Hi, Although not a problem that can't be overcome the bugs demonstrated in my above post are still extant in V7.21 Regards davidb
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. Mmm, another clue - If you reverse the order of your values so that the highest occurs first then the example again works. Regards davidb
  11. 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
  12. How about a union?: union { unsigned long ulong; unsigned char byte[4]; }mylong;   mylong.ulong = 0x12345678; unsigned char byte0 = mylong.byte[0]; unsigned char byte1 = mylong.byte[1]; unsigned char byte2 = mylong.byte[2]; unsigned char byte3 = mylong.byte[3]; Not tested! Regards davidb
  13. 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
  14. 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
  15. 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
  • Create New...