| 
	
	|  |  |  
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| kWoody_uk 
 
 
 Joined: 29 Jan 2015
 Posts: 47
 Location: United Kingdom
 
 
			    
 
 | 
			
				| Slave select on pic18f4423 |  
				|  Posted: Tue Mar 31, 2015 1:19 pm |   |  
				| 
 |  
				| Hi Guys, 
 I think there is a problem with the Slave Select for Spi on the pic18f4423 and would like another pair of eyes to look at the silicon errata data and confirm the bad news I have come to.
 
 http://ww1.microchip.com/downloads/en/DeviceDoc/80289e.pdf
 
 It's section 1 in this document (Module: MSSP)
 
 My spi interrupt is firing whenever there are 8 clock pulses, whether the slave select line is low or not.
 
 I have checked and confirmed the CCS assembly listing to ensure the Slave select line is in use and not just IO and that it is selected as an input.
 
 Unfortunately, I've only discovered this after the product has been assembled (I should have read the errata more carefully!)  Apart from using the SS line as general IO and polling to see if low before awaiting the data, is there a better work-around?
 
 Thanks in advance,
 
 
 Keith
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Mar 31, 2015 1:39 pm |   |  
				| 
 |  
				| The obvious question is how long your master device allows from the SS dropping to starting to send the data?. This is the problem, but only if this is a very short time (depends on yous CPU clock rate). Needs to be 12 cycles of your PIC master clock, |  |  
		|  |  
		| kWoody_uk 
 
 
 Joined: 29 Jan 2015
 Posts: 47
 Location: United Kingdom
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Mar 31, 2015 2:58 pm |   |  
				| 
 |  
				| Hi Ttelmah, 
 I'm waiting about 30 cycles. However, I know it isn't this, as even when the slave select is permanently high, the spi interrupt is still entered whenever there are 8 clock pulses... It's almost like enabling the use of the slave select line is being ignored by the pic.
 
 Keith
 |  |  
		|  |  
		| PCM programmer 
 
 
 Joined: 06 Sep 2003
 Posts: 21708
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Tue Mar 31, 2015 10:54 pm |   |  
				| 
 |  
				| If you can post small, working SPI master and slave programs, we can test it.  These two programs can be really short (but compilable).
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 1:06 am |   |  
				| 
 |  
				| I have just put this together on a 4423, and it works correctly (at least on a basic test...). 
  	  | Code: |  	  | #include <18F4423.h>
 //Basic setups adjust to suit your device
 #device ADC=10
 #fuses HS, NOFCMEN, NOWDT, STVREN, NOXINST, NOPROTECT, NODEBUG, BROWNOUT, BORV43
 #use delay(crystal=20000000)
 
 //Basic SPI slave test
 #use RS232(UART1, baud=9600, ERRORS)
 //SPI mode definitions
 #define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
 #define SPI_MODE_1  (SPI_L_TO_H)
 #define SPI_MODE_2  (SPI_H_TO_L)
 #define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)
 
 //Basic buffer code -setup 16byte buffers both ways
 int8 btempSPIRX,btempSPITX;
 #define SIBUFF (16) //buffer sizes
 typedef struct {
 int8 in;
 int8 out;
 int8 buff[SIBUFF];
 } buffer;
 
 buffer SPIRX,SPITX; //buffers
 
 //Macros to handle buffers
 #define incin(buff) ((buff.in==(SIBUFF-1))?0:buff.in+1)
 #define incout(buff) ((buff.out==(SIBUFF-1))?0:buff.out+1)
 #define isempty(buff) (buff.in==buff.out)
 #define hasdata(buff) (buff.in!=buff.out)
 #define isfull(buff) ((incin(buff)==buff.out)
 #define tobuff(bname,c) { bname.buff[bname.in]=c;\
 bname.in=incin(bname);\
 if (bname.in==bname.out) bname.out=incout(bname);\
 }
 #define frombuff(bname) (btemp##bname=bname.buff[bname.out],\
 bname.out=incout(bname), \
 btemp##bname)
 #define clrbuff(buff) buff.in=buff.out=0
 
 //Because CCS code tests unecessarily just do direct SPI I/O
 #byte SSPBUF=getenv("SFR:SSPBUF")
 #INT_SSP
 void SPI(void)
 {
 //have seen SPI transfer
 tobuff(SPIRX,SSPBUF); //read incoming
 if (hasdata(SPITX)) //if data is waiting to send
 {
 SSPBUF=frombuff(SPITX); //load next outgoing
 }
 }
 
 void main()
 {
 int8 chr, ctr=0;
 setup_spi(SPI_MODE_0 | SPI_SLAVE);
 clrbuff(SPIRX);
 clrbuff(SPITX); //clear both buffers
 //Now several setups must happen. Analog must be off on A5
 setup_adc_ports(NO_ANALOGS); //obviously if using the analog enable other pins
 setup_adc(ADC_OFF);
 setup_ccp1(CCP_OFF);
 //comparator 2 must be off
 setup_comparator(NC_NC_NC_NC);
 
 enable_interrupts(GLOBAL);
 enable_interrupts(INT_SSP); //enable the slave interrupts
 while(TRUE)
 {
 //Now sit and wait for something on the SSP
 if (hasdata(SPIRX)) //something has been received
 {
 chr=frombuff(SPIRX); //get the received character
 //do something - minimum demo
 if (chr=='R')
 {
 tobuff(SPITX,ctr++); //send a byte back
 }
 }
 }
 }
 
 | 
 If I hold the SS high, I can toggle C3, and no interrupt occurs. Drop A5, and toggle C3, and after eight cycles it interrupts.
 
 Remember there needs to be long enough after _every_ byte, to allow time for the slave to have reached the interrupt, serviced it, and returned. As written here, about 20uSec/byte maximum. As written, if the SPI sends the character 'R', then waits, and clocks out a dummy byte, it received back a count.
 
 I wonder if you are forgetting to turn off the analog port on pin A5?. If this is not off, SS does not work. Same with comparator 2.
 |  |  
		|  |  
		| kWoody_uk 
 
 
 Joined: 29 Jan 2015
 Posts: 47
 Location: United Kingdom
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 2:17 am |   |  
				| 
 |  
				| You've cracked it Ttelmah! 
 I am using the analogue pins, and when I disabled this the SS works.
 
 Unfortunately, with my application, I am using the analogue pins ( AN5 upwards) and on this device, I don't think you can individually set which pins are Analogue, but must accept the choices given... Doh!!
 
 Any suggestions would be gratefully accepted.
 
 Thanks,
 
 
 Keith
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 2:37 am |   |  
				| 
 |  
				| Change the chip...... 
 Unfortunately this was something you needed to spot at the design. 'And upwards', is the exact opposite of how this chip allows the analogs to be selected. You can use AN3 _and down_ as analogs, but not AN5 'and up'.
 
 Unfortunately, most of the chips that offer the same ADC resolution and are completely compatible, have at least one pin different (VddCore on the ones that internally run at a lower voltage, or USB pins for example). The ones that directly slot in place have the same ADC restrictions. The nearest is probably the 45K80, if you can add a capacitor for the VddCore pin, then this allows every ADC pin to be individually selected
 |  |  
		|  |  
		| kWoody_uk 
 
 
 Joined: 29 Jan 2015
 Posts: 47
 Location: United Kingdom
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 3:39 am |   |  
				| 
 |  
				| Yeah I know, I would have used the 46k22 as I like this chip and know it's short-comings, but my boss wanted 12bit ADC resolution and we'd used this before, but only in Master SPI mode. 
 Thanks for the suggestion; I'll consider this in future.
 
 Lesson learnt.  Next time, I'll read the data sheet 50 times through :-)
 
 Thanks again,
 
 
 Keith
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 3:45 am |   |  
				| 
 |  
				| The 45K80, has the same 12bit ADC resolution. That's why I mentioned this one.  |  |  
		|  |  
		| kWoody_uk 
 
 
 Joined: 29 Jan 2015
 Posts: 47
 Location: United Kingdom
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 4:04 am |   |  
				| 
 |  
				| Oh Blimey   
 That's even better.  I don't know how you do it for the money ;-)
 
 - but thank you!
 
 
 Keith
 |  |  
		|  |  
		| temtronic 
 
 
 Joined: 01 Jul 2010
 Posts: 9588
 Location: Greensville,Ontario
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 4:56 am |   |  
				| 
 |  
				| yeesh , bosses, 12 bit vs 10 bits... 
 hope he's paying you lots for those extra 2 bits! Board layout, signal conditioning, wiring, PSU...ALL have to be PERFECT to acquire usable 12bits.
 
 Depending on the application, it might be better and cheaper to go with solid 10 bits than 'hit and miss' 12 bits.
 
 just my 2 cents worth
 
 Jay
 |  |  
		|  |  
		| kWoody_uk 
 
 
 Joined: 29 Jan 2015
 Posts: 47
 Location: United Kingdom
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 7:20 am |   |  
				| 
 |  
				| Thanks Jay, 
 All input is appreciated.  Luckily, my boss is great at analogue design (an art which is disappearing) so that's looked after.
 
 Keith
 |  |  
		|  |  
		| Ttelmah 
 
 
 Joined: 11 Mar 2010
 Posts: 19966
 
 
 
			    
 
 | 
			
				|  |  
				|  Posted: Wed Apr 01, 2015 7:36 am |   |  
				| 
 |  
				| True. 
 It's worth also realising that the 'extras' depend a lot on the 'nature' of the actual data.
 For things like audio signals, the noise constraints etc., are all there, but the 'accuracy/repeatability' ones are not. It doesn't matter if a value reads as 2623 one day and 2625 another. What matters is that a value that has dropped by a tiny percentage really does read 2 lower each day. However if being used for an actual measurement application, then (of course) you want the same reading each day, so the accuracy required spreads to things like the stability of the Vref etc...
 
 It's actually surprising just how good the 10bit PIC ADC really can be, if used with good design, and a really good reference. I've had systems that give repeatable values to 0.1% over long periods.
 |  |  
		|  |  
		|  |  
  
	| 
 
 | You cannot post new topics in this forum You cannot reply to topics in this forum
 You cannot edit your posts in this forum
 You cannot delete your posts in this forum
 You cannot vote in polls in this forum
 
 |  
 Powered by phpBB © 2001, 2005 phpBB Group
 
 |