|
|
View previous topic :: View next topic |
Author |
Message |
joshkeys
Joined: 16 Aug 2005 Posts: 37 Location: Fredericton,NB
|
i2c communication problems |
Posted: Tue Aug 16, 2005 6:20 pm |
|
|
Hi there, i am using i2c for the first time and am having a few problems.
First of all, i am using a pic 18f452 as my master, and pic18f4431 as my slave. i have pullup resistors on both the clock and data lines, and if try to communicate by either a read or write command to the slave i can see a perfect transmission of data from the master to the slave.
For example. If I want to write 0x10 to the slave (address 0x1), I issue a start command, write the address, write the first byte, write the second byte, and issue a stop command. When i use the oscilloscope i can see that everyting went 100% fine.
The problem is that the slave has absolutley no knowledge of any i2c interactions because the only functions of the slave right now are to interrupt (ssp interrupt) if there is communication detected and turn a pin on. Also to further check i polled the BF bit of the SSPSTAT register and it always reads 0 (buffer empty).
Also if i was to initiate a read command from the master, i would issue a start bit, then a read(1), followed by a read(0), then a stop. What i see on the oscilloscope is a series of 1's are recieved due to the pullup resistor.
What it seems is as if the PIC is not even in i2c mode because it just sits there and the only reason an acknowledge is recieved from the slave is because of the pullup resistor.
On the slave (pic18f4431) I am using what i assumed to be the default i2c pins (pin_D3 for SCL and PIN_D2 for SDA). I tried using the alternate pins also (pin_C5 and Pin_C4), but they do not allow the clock to go high (I assume because it is set to output). I know that in order to use the alternate pins you need to access the config3h register, but i just wanted to make i wasnt confused as of to which was the default pins.
I hope that i have included everythign that is necessary for someone to help me.. oh. also i have tried forcing hardware and not forcing hardware on both. So thats it.. someone please help as i am stumped.
Regards
Josh
P.s. This is my setup for the slave
#define SDA_PIN pin_D2
#define SCL_PIN pin_D3
#use i2c(Slave,slow,sda=SDA_PIN,scl=SCL_PIN,address=0x01,force_hw)
And for the master
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 16, 2005 6:39 pm |
|
|
You need hardware i2c for the slave.
You need to use pins C4 and C3 (SDA and SCL) for hardware i2c in the 18F4431. |
|
|
joshkeys
Joined: 16 Aug 2005 Posts: 37 Location: Fredericton,NB
|
|
Posted: Tue Aug 16, 2005 6:50 pm |
|
|
Do you mean C4 and C5 pins. because if you look at the data sheet for the 18f4431 pin_C3 is RC3/T0CKl/T5CKL/INT0. It is Pin C4 and C5 that are for SDA and SCL. Anyways I tried using them and forcing hardware and this time it didnt freeze but worked the same as pin D2 and D3. Although the clock was a lot cleaner. But ssp never interrupted still. and the buffer status bit never came on. imply the pic is still oblivious to i2c communications going on.
Josh |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 16, 2005 7:07 pm |
|
|
I am sorry. I jumped the gun on that one. You are correct. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 16, 2005 7:14 pm |
|
|
What version of the PCH compiler do you have ? If I have your
version, I can look at the ASM code and check if it's correct. |
|
|
joshkeys
Joined: 16 Aug 2005 Posts: 37 Location: Fredericton,NB
|
|
Posted: Tue Aug 16, 2005 7:31 pm |
|
|
The version is 3.231. Do you want an entire copy and paste of the ASM file? or just an excert of the i2c functions.. it is a little lengthy as i am implementing a PI controller for a robot and setting up a communication protocol.. but not too lengthy.. just tell lme what you want.
Josh
P.s. Thanks a ton! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 16, 2005 8:10 pm |
|
|
The only thing I'd need is your INT_SSP isr.
I sort of assumed that you're using the EX_SLAVE.C example
provided by CCS. If not, then post your isr code. |
|
|
Guest
|
|
Posted: Tue Aug 16, 2005 8:29 pm |
|
|
Well just so you know, it isnt even entering the isr.. it never leaves the while(1) loop.. but here it is. This is the whole ASM file just to avoid any possible things missing.. sorry about the length and lack of documentation. I am still in the middle of putting stuff together.. just stuck with the i2c right now. I initially was using rs232 to communicate between pics.. but wanted to up the speed.. and also curious about the workings of i2c. Thanks again!
CCS PCH C Compiler, Version 3.231, 28727 16-Aug-05 23:25
Filename: H:\Thesis\PIC18F4431\thesis11.LST
ROM used: 5196 bytes (33%)
Largest free fragment is 10352
RAM used: 181 (24%) at main() level
225 (30%) worst case
Stack: 6 worst case (2 in main + 4 for interrupts)
*
0000: GOTO 12D6
*
0008: MOVFF FE8,05
000C: MOVFF FD8,06
0010: MOVFF FE0,07
0014: MOVLB 0
0016: MOVFF FE9,0D
001A: MOVFF FEA,08
001E: MOVFF FE1,09
0022: MOVFF FE2,0A
0026: MOVFF FD9,0B
002A: MOVFF FDA,0C
002E: MOVFF FF3,14
0032: MOVFF FF4,15
0036: MOVFF FFA,16
003A: MOVFF 00,0F
003E: MOVFF 01,10
0042: MOVFF 02,11
0046: MOVFF 03,12
004A: MOVFF 04,13
004E: BTFSS FF0.3
0050: GOTO 005A
0054: BTFSC FF0.0
0056: GOTO 10F0
005A: BTFSS F9D.3
005C: GOTO 0066
0060: BTFSC F9E.3
0062: GOTO 01FA
0066: MOVFF 0F,00
006A: MOVFF 10,01
006E: MOVFF 11,02
0072: MOVFF 12,03
0076: MOVFF 13,04
007A: MOVFF 0D,FE9
007E: MOVFF 08,FEA
0082: MOVFF 09,FE1
0086: MOVFF 0A,FE2
008A: MOVFF 0B,FD9
008E: MOVFF 0C,FDA
0092: MOVFF 14,FF3
0096: MOVFF 15,FF4
009A: MOVFF 16,FFA
009E: MOVFF 05,FE8
00A2: MOVFF 07,FE0
00A6: MOVFF 06,FD8
00AA: RETFIE 0
.................... #include "H:\Thesis\PIC18F4431\thesis11.h"
.................... #include <18F4431.h>
.................... //////// Standard Header file for the PIC18F4431 device ////////////////
.................... #device PIC18F4431
.................... #list
....................
.................... #device ICD=TRUE
.................... #device adc=10
.................... #use delay(clock=40000000)
.................... #fuses NOWDT,WDT128,HS, NOPROTECT, IESO, BROWNOUT, BORV27, NOPUT, NOCPD, STVREN, DEBUG, NOLVP, NOWRT, NOWRTD, FCMEN, NOWINEN, T1LOWPOWER, HPOL_HIGH, NOWRTC, NOWRTB, NOEBTR, NOEBTRB, NOCPB, LPOL_HIGH, PWMPIN, NOMCLR, FLTAC1, SSP_RC
....................
....................
....................
.................... #include <stdlib.h>
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2003 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef _STDLIB
.................... #define _STDLIB
....................
.................... //---------------------------------------------------------------------------
.................... // Definitions and types
.................... //---------------------------------------------------------------------------
....................
.................... #ifndef RAND_MAX
.................... #define RAND_MAX 32767 // The value of which is the maximum value
.................... // ... returned by the rand function
.................... #endif
....................
.................... typedef struct {
.................... signed int quot;
.................... signed int rem;
.................... } div_t;
....................
.................... typedef struct {
.................... signed long quot;
.................... signed long rem;
.................... } ldiv_t;
....................
.................... #include <stddef.h>
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2003 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef _STDDEF
....................
.................... #define _STDDEF
....................
.................... #if sizeof(int *)==1
.................... #define ptrdiff_t int
.................... #else
.................... #define ptrdiff_t long
.................... #endif
....................
.................... #define size_t int
.................... #define wchar_t char
.................... #define NULL 0
....................
.................... #define offsetof(s,f) (offsetofbit(s,f)/8)
....................
.................... #endif
....................
....................
.................... //---------------------------------------------------------------------------
.................... // String conversion functions
.................... //---------------------------------------------------------------------------
....................
.................... /* Standard template: float atof(char * s)
.................... * converts the initial portion of the string s to a float.
.................... * returns the converted value if any, 0 otherwise
.................... */
.................... float atof(char * s);
....................
.................... /* Standard template: float atoe(char * s)
.................... * converts the initial portion of the string s to a float.
.................... * returns the converted value if any, 0 otherwise
.................... * also handles E format numbers
.................... */
.................... float atoe(char * s);
....................
.................... /* Standard template: signed int atoi(char * s)
.................... * converts the initial portion of the string s to a signed int
.................... * returns the converted value if any, 0 otherwise
.................... */
.................... signed int atoi(char *s);
....................
.................... /* Syntax: signed int32 atoi32(char * s)
.................... converts the initial portion of the string s to a signed int32
.................... returns the converted value if any, 0 otherwise*/
.................... signed int32 atoi32(char *s);
....................
.................... /* Syntax: char * itoa(signed int32 num, int8 base, char * s)
.................... converts the signed int32 to a string and
.................... returns the converted value if any, 0 otherwise*/
.................... char * itoa(signed int32 num, int8 base, char * s);
....................
.................... /* Standard template: signed long atol(char * s)
.................... * converts the initial portion of the string s to a signed long
.................... * returns the converted value if any, 0 otherwise
.................... */
.................... signed long atol(char *s);
....................
.................... /* Standard template: float strtol(char * s,char *endptr)
.................... * converts the initial portion of the string s to a float
.................... * returns the converted value if any, 0 otherwise
.................... * the final string is returned in the endptr, if endptr is not null
.................... */
.................... float strtod(char *s,char *endptr);
....................
.................... /* Standard template: long strtoul(char * s,char *endptr,signed int base)
.................... * converts the initial portion of the string s, represented as an
.................... * integral value of radix base to a signed long.
.................... * Returns the converted value if any, 0 otherwise
.................... * the final string is returned in the endptr, if endptr is not null
.................... */
.................... signed long strtol(char *s,char *endptr,signed int base);
....................
.................... /* Standard template: long strtoul(char * s,char *endptr,signed int base)
.................... * converts the initial portion of the string s, represented as an
.................... * integral value of radix base to a unsigned long.
.................... * returns the converted value if any, 0 otherwise
.................... * the final string is returned in the endptr, if endptr is not null
.................... */
.................... long strtoul(char *s,char *endptr,signed int base);
....................
.................... //---------------------------------------------------------------------------
.................... // Pseudo-random sequence generation functions
.................... //---------------------------------------------------------------------------
....................
.................... /* The rand function computes a sequence of pseudo-random integers in
.................... * the range 0 to RAND_MAX
.................... *
.................... * Parameters:
.................... * (none)
.................... *
.................... * Returns:
.................... * The pseudo-random integer
.................... */
.................... long rand(void);
....................
.................... /* The srand function uses the argument as a seed for a new sequence of
.................... * pseudo-random numbers to be returned by subsequent calls to rand.
.................... *
.................... * Parameters:
.................... * [in] seed: The seed value to start from. You might need to pass
.................... *
.................... * Returns:
.................... * (none)
.................... *
.................... * Remarks
.................... * The srand function sets the starting point for generating
.................... * a series of pseudorandom integers. To reinitialize the
.................... * generator, use 1 as the seed argument. Any other value for
.................... * seed sets the generator to a random starting point. rand
.................... * retrieves the pseudorandom numbers that are generated.
.................... * Calling rand before any call to srand generates the same
.................... * sequence as calling srand with seed passed as 1.
.................... * Usually, you need to pass a time here from outer source
.................... * so that the numbers will be different every time you run.
.................... */
.................... void srand(unsigned int32 seed);
....................
.................... //---------------------------------------------------------------------------
.................... // Memory management functions
.................... //---------------------------------------------------------------------------
....................
.................... // Comming soon
....................
.................... //---------------------------------------------------------------------------
.................... // Communication with the environment
.................... //---------------------------------------------------------------------------
....................
.................... /* The function returns 0 always
.................... */
.................... signed int system(char *string);
....................
.................... //---------------------------------------------------------------------------
.................... // Searching and sorting utilities
.................... //---------------------------------------------------------------------------
....................
.................... /* Performs a binary search of a sorted array..
.................... *
.................... * Parameters:
.................... * [in] key: Object to search for
.................... * [in] base: Pointer to base of search data
.................... * [in] num: Number of elements
.................... * [in] width: Width of elements
.................... * [in] compare: Function that compares two elements
.................... *
.................... * Returns:
.................... * bsearch returns a pointer to an occurrence of key in the array pointed
.................... * to by base. If key is not found, the function returns NULL. If the
.................... * array is not in order or contains duplicate records with identical keys,
.................... * the result is unpredictable.
.................... */
.................... //void *bsearch(const void *key, const void *base, size_t num, size_t width,
.................... // int (*compare)(const void *, const void *));
....................
.................... /* Performs the shell-metzner sort (not the quick sort algorithm). The contents
.................... * of the array are sorted into ascending order according to a comparison
.................... * function pointed to by compar.
.................... *
.................... * Parameters:
.................... * [in] base: Pointer to base of search data
.................... * [in] num: Number of elements
.................... * [in] width: Width of elements
.................... * [in] compare: Function that compares two elements
.................... *
.................... * Returns:
.................... * (none)
.................... */
.................... //void *qsort(const void *base, size_t num, size_t width,
.................... // int (*compare)(const void *, const void *));
....................
.................... //---------------------------------------------------------------------------
.................... // Integer arithmetic functions
.................... //---------------------------------------------------------------------------
....................
.................... #define labs abs
....................
.................... div_t div(signed int numer,signed int denom);
.................... ldiv_t ldiv(signed long numer,signed long denom);
....................
.................... //---------------------------------------------------------------------------
.................... // Multibyte character functions
.................... //---------------------------------------------------------------------------
....................
.................... // Not supported
....................
.................... //---------------------------------------------------------------------------
.................... // Multibyte string functions
.................... //---------------------------------------------------------------------------
....................
.................... // Not supported
....................
....................
.................... //---------------------------------------------------------------------------
.................... // Internal implementation
.................... //---------------------------------------------------------------------------
....................
.................... #include <stddef.h>
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2003 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef _STDDEF
....................
.................... #define _STDDEF
....................
.................... #if sizeof(int *)==1
.................... #define ptrdiff_t int
.................... #else
.................... #define ptrdiff_t long
.................... #endif
....................
.................... #define size_t int
.................... #define wchar_t char
.................... #define NULL 0
....................
.................... #define offsetof(s,f) (offsetofbit(s,f)/8)
....................
.................... #endif
....................
.................... #include <string.h>
.................... ////////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2003 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ////////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef _STRING
.................... #define _STRING
.................... #include <stddef.h>
.................... ///////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2003 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ///////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef _STDDEF
....................
.................... #define _STDDEF
....................
.................... #if sizeof(int *)==1
.................... #define ptrdiff_t int
.................... #else
.................... #define ptrdiff_t long
.................... #endif
....................
.................... #define size_t int
.................... #define wchar_t char
.................... #define NULL 0
....................
.................... #define offsetof(s,f) (offsetofbit(s,f)/8)
....................
.................... #endif
....................
.................... #include <ctype.h>
.................... ////////////////////////////////////////////////////////////////////////////
.................... //// (C) Copyright 1996,2003 Custom Computer Services ////
.................... //// This source code may only be used by licensed users of the CCS C ////
.................... //// compiler. This source code may only be distributed to other ////
.................... //// licensed users of the CCS C compiler. No other use, reproduction ////
.................... //// or distribution is permitted without written permission. ////
.................... //// Derivative programs created using this software in object code ////
.................... //// form are not restricted in any way. ////
.................... ////////////////////////////////////////////////////////////////////////////
....................
.................... #ifndef _CTYPE
.................... #define _CTYPE
....................
.................... #define islower(x) isamong(x,"abcdefghijklmnopqrstuvwxyz")
.................... #define isupper(x) isamong(x,"ABCDEFGHIJKLMNOPQRSTUVWXYZ")
.................... #define isalnum(x) isamong(x,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
.................... #define isalpha(x) isamong(x,"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
.................... #define isdigit(x) isamong(x,"0123456789")
.................... #define isspace(x) (x==' ')
.................... #define isxdigit(x) isamong(x,"0123456789ABCDEFabcdef")
.................... #define iscntrl(x) (x<' ')
.................... #define isprint(x) (x>=' ')
.................... #define isgraph(x) (x>' ')
.................... #define ispunct(x) ((x>' ')&&!isalnum(x))
....................
.................... #endif
....................
....................
....................
....................
....................
.................... //////////////////////////////////////////////
.................... //// Uncomment the following define to ////
.................... //// allow some functions to use a ////
.................... //// quicker algorithm, but use more ROM ////
.................... //// ////
.................... //// #define FASTER_BUT_MORE_ROM ////
.................... //////////////////////////////////////////////
....................
....................
....................
.................... /*Copying functions*/
.................... /* standard template:
.................... void *memmove(void *s1, void *s2, size_t n).
.................... Copies max of n characters safely (not following ending '\0')
.................... from s2 in s1; if s2 has less than n characters, appends 0 */
....................
.................... char *memmove(void *s1,char *s2,size_t n)
.................... {
.................... char *sc1;
.................... char *sc2;
.................... sc1=s1;
.................... sc2=s2;
.................... if(sc2<sc1 && sc1 <sc2 +n)
.................... for(sc1+=n,sc2+=n;0<n;--n)
.................... *--sc1=*--sc2;
.................... else
.................... for(;0<n;--n)
.................... *sc1++=*sc2++;
.................... return s1;
.................... }
....................
.................... /* compiler ignored the name 'strcpy()'; perhaps, it's reserved?
.................... Standard template: char *strcpy(char *s1, const char *s2)
.................... copies the string s2 including the null character to s1*/
....................
.................... char *strcopy(char *s1, char *s2)
.................... {
.................... char *s;
....................
.................... for (s = s1; *s2 != 0; s++, s2++) {
.................... *s = *s2;
.................... }
.................... *s = *s2;
.................... return(s1);
.................... }
....................
.................... /* standard template:
.................... char *strncpy(char *s1, const char *s2, size_t n).
.................... Copies max of n characters (not following ending '\0')
.................... from s2 in s1; if s2 has less than n characters, appends 0 */
....................
.................... char *strncpy(char *s1, char *s2, size_t n)
.................... {
.................... char *s;
....................
.................... for (s = s1; n > 0 && *s2 != '\0'; n--)
.................... *s++ = *s2++;
.................... for (; n > 0; n--)
.................... *s++ = '\0';
....................
.................... return(s1);
.................... }
.................... /***********************************************************/
....................
.................... /*concatenation functions*/
.................... /* standard template: char *strcat(char *s1, const char *s2)
.................... appends s2 to s1*/
....................
.................... char *strcat(char *s1, char *s2)
.................... {
.................... char *s;
....................
.................... for (s = s1; *s != '\0'; ++s);
.................... while(*s2 != '\0')
.................... {
.................... *s = *s2;
.................... ++s;
.................... ++s2;
.................... }
....................
.................... *s = '\0';
.................... return(s1);
.................... }
.................... /* standard template: char *strncat(char *s1, char *s2,size_t n)
.................... appends not more than n characters from s2 to s1*/
....................
.................... char *strncat(char *s1, char *s2, size_t n)
.................... {
.................... char *s;
....................
.................... for (s = s1; *s != '\0'; ++s);
.................... while(*s2 != '\0' && 0<n)
.................... {
.................... *s = *s2;
.................... ++s;
.................... ++s2;
.................... --n;
.................... }
....................
.................... *s = '\0';
.................... return(s1);
.................... }
....................
.................... /***********************************************************/
....................
....................
.................... /*comparison functions*/
.................... /* standard template: signed int memcmp(void *s1, void *s2).
.................... Compares s1 & s2; returns -1 if s1<s2, 0 if s1=s2, 1 if s1>s2 */
....................
.................... signed int memcmp(void * s1,char *s2,size_t n)
.................... {
.................... char *su1, *su2;
.................... for(su1=s1, su2=s2; 0<n; ++su1, ++su2, --n)
.................... {
.................... if(*su1!=*su2)
.................... return ((*su1<*su2)?1:+1);
.................... }
.................... return 0;
.................... }
....................
.................... /* standard template: int strcmp(const char *s1, const char *s2).
.................... Compares s1 & s2; returns -1 if s1<s2, 0 if s1=s2, 1 if s1>s2 */
....................
.................... signed int strcmp(char *s1, char *s2)
.................... {
.................... for (; *s1 == *s2; s1++, s2++)
.................... if (*s1 == '\0')
.................... return(0);
.................... return((*s1 < *s2) ?-1: 1);
.................... }
.................... /* standard template: int strcoll(const char *s1, const char *s2).
.................... Compares s1 & s2; returns -1 if s1<s2, 0 if s1=s2, 1 if s1>s2 */
....................
.................... signed int strcoll(char *s1, char *s2)
.................... {
.................... for (; *s1 == *s2; s1++, s2++)
.................... if (*s1 == '\0')
.................... return(0);
.................... return((*s1 < *s2) ?-1: 1);
.................... }
....................
.................... /* standard template:
.................... int strncmp(const char *s1, const char *s2, size_t n).
.................... Compares max of n characters (not following 0) from s1 to s2;
.................... returns same as strcmp */
....................
.................... signed int strncmp(char *s1, char *s2, size_t n)
.................... {
.................... for (; n > 0; s1++, s2++, n--)
.................... if (*s1 != *s2)
.................... return((*s1 <*s2) ?-1: 1);
.................... else if (*s1 == '\0')
.................... return(0);
.................... return(0);
.................... }
.................... /* standard template:
.................... int strxfrm(const char *s1, const char *s2, size_t n).
.................... transforms maximum of n characters from s2 and places them into s1*/
.................... size_t strxfrm(char *s1, char *s2, size_t n)
.................... {
.................... char *s;
.................... int n1;
.................... n1=n;
.................... for (s = s1; n > 0 && *s2 != '\0'; n--)
.................... *s++ = *s2++;
.................... for (; n > 0; n--)
.................... *s++ = '\0';
....................
.................... return(n1);
.................... }
....................
....................
....................
....................
....................
.................... /***********************************************************/
.................... /*Search functions*/
.................... /* standard template: void *memchr(const char *s, int c).
.................... Finds first occurrence of c in n characters of s */
....................
.................... char *memchr(void *s,int c,size_t n)
.................... {
.................... char uc;
.................... char *su;
.................... uc=c;
.................... for(su=s;0<n;++su,--n)
.................... if(*su==uc)
.................... return su;
.................... return NULL;
.................... }
....................
.................... /* standard template: char *strchr(const char *s, int c).
.................... Finds first occurrence of c in s */
....................
.................... char *strchr(char *s, int c)
.................... {
.................... for (; *s != c; s++)
.................... if (*s == '\0')
.................... return(0);
.................... return(s);
.................... }
.................... /* standard template:
.................... size_t strcspn(const char *s1, const char *s2).
.................... Computes length of max initial segment of s1 that
.................... consists entirely of characters NOT from s2*/
....................
.................... int *strcspn(char *s1, char *s2)
.................... {
.................... char *sc1, *sc2;
....................
.................... for (sc1 = s1; *sc1 != 0; sc1++)
.................... for (sc2 = s2; *sc2 != 0; sc2++)
.................... if (*sc1 == *sc2)
.................... return(sc1 - s1);
.................... return(sc1 - s1);
.................... }
.................... /* standard template:
.................... char *strpbrk(const char *s1, const char *s2).
.................... Locates first occurence of any character from s2 in s1;
.................... returns s1 if s2 is empty string */
....................
.................... char *strpbrk(char *s1, char *s2)
.................... {
.................... char *sc1, *sc2;
....................
.................... for (sc1 = s1; *sc1 != 0; sc1++)
.................... for (sc2 = s2; *sc2 != 0; sc2++)
.................... if (*sc1 == *sc2)
.................... return(sc1);
.................... return(0);
.................... }
....................
....................
.................... /* standard template: char *strrchr(const char *s, int c).
.................... Finds last occurrence of c in s */
....................
.................... char *strrchr(char *s, int c)
.................... {
.................... char *p;
....................
.................... for (p = 0; ; s++)
.................... {
.................... if (*s == c)
.................... p = s;
.................... if (*s == '\0')
.................... return(p);
.................... }
.................... }
.................... /* computes length of max initial segment of s1 consisting
.................... entirely of characters from s2 */
....................
.................... int *strspn(char *s1, char *s2)
.................... {
.................... char *sc1, *sc2;
....................
.................... for (sc1 = s1; *sc1 != 0; sc1++)
.................... for (sc2 = s2; ; sc2++)
.................... if (*sc2 == '\0')
.................... return(sc1 - s1);
.................... else if (*sc1 == *sc2)
.................... break;
.................... return(sc1 - s1);
.................... }
.................... /* standard template:
.................... char *strstr(const char *s1, const char *s2);
.................... Locates first occurence of character sequence s2 in s1;
.................... returns 0 if s2 is empty string
....................
.................... Uncomment #define FASTER_BUT_MORE_ROM at the top of the
.................... file to use the faster algorithm */
.................... char *strstr(char *s1, char *s2)
.................... {
.................... char *s, *t;
....................
.................... #ifdef FASTER_BUT_MORE_ROM
.................... if (*s2 == '\0')
.................... return(s1);
.................... #endif
....................
.................... while (*s1)
.................... {
.................... for(s = s1, t = s2; *t && *s == *t; ++s, ++t);
....................
.................... if (*t == '\0')
.................... return s1;
.................... ++s1;
.................... #ifdef FASTER_BUT_MORE_ROM
.................... while(*s1 != '\0' && *s1 != *s2)
.................... ++s1;
.................... #endif
.................... }
.................... return 0;
.................... }
....................
.................... /* standard template: char *strtok(char *s1, const char *s2).
....................
.................... Finds next token in s1 delimited by a character from separator
.................... string s2 (which can be different from call to call). First call
.................... starts at beginning of s1 searching for first character NOT
.................... contained in s2; returns 0 if none is found.
.................... If one is found, it is the start of first token (return value).
.................... Function then searches from there for a character contained in s2.
.................... If none is found, current token extends to end of s1, and subsequent
.................... searches for a token will return 0. If one is found, it is
.................... overwritten by '\0', which terminates current token. Function saves
.................... pointer to following character from which next search will start.
.................... Each subsequent call, with 0 as first argument, starts searching
.................... from saved pointer */
....................
.................... char *strtok(char *s1, char *s2)
.................... {
.................... char *beg, *end;
.................... static char *save;
....................
.................... beg = (s1)?s1: save;
.................... beg += strspn(beg, s2);
.................... if (*beg == '\0')
.................... {
.................... *save = ' ';
.................... return(0);
.................... }
.................... end = strpbrk(beg, s2);
.................... if (*end != '\0')
.................... {
.................... *end = '\0';
.................... end++;
.................... }
.................... save = end;
.................... return(beg);
.................... }
....................
.................... /*****************************************************************/
.................... /*Miscellaneous functions*/
.................... /* standard template
.................... maps error number in errnum to an error message string
.................... Returns: Pointer to string
.................... */
.................... #ifdef _ERRNO
.................... char * strerror(int errnum)
.................... {
.................... char s[15];
.................... switch( errnum)
.................... {
.................... case 0:
.................... strcpy(s,"no errors");
.................... return s;
.................... case EDOM :
.................... strcpy(s,"domain error");
.................... return s;
.................... case ERANGE:
.................... strcpy(s,"range error");
.................... return s;
.................... }
.................... }
.................... #ENDIF
.................... /* standard template: size_t strlen(const char *s).
.................... Computes length of s1 (preceding terminating 0) */
....................
.................... int *strlen(char *s)
.................... {
.................... char *sc;
....................
.................... for (sc = s; *sc != 0; sc++);
.................... return(sc - s);
.................... }
....................
.................... /* standard template: size_t stricmp(const char *s1, const char *s2).
.................... Compares s1 to s2 ignoring case (upper vs. lower) */
....................
.................... signed int stricmp(char *s1, char *s2)
.................... {
.................... for(; *s1==*s2||(isalpha(*s1)&&isalpha(*s2)&&(*s1==*s2+32||*s2==*s1+32));
.................... s1++, s2++)
.................... if (*s1 == '\0')
.................... return(0);
.................... return((*s1 < *s2) ?-1: 1);
.................... }
....................
....................
.................... /* standard template: char *strlwr(char *s).
.................... Replaces uppercase letters by lowercase;
.................... returns pointer to new string s */
....................
.................... char *strlwr(char *s)
.................... {
.................... char *p;
....................
.................... for (p = s; *p != '\0'; p++)
.................... if (*p >= 'A' && *p <='Z')
.................... *p += 'a' - 'A';
.................... return(s);
.................... }
....................
....................
.................... /************************************************************/
....................
....................
.................... #endif
....................
....................
.................... div_t div(signed int numer,signed int denom)
.................... {
.................... div_t val;
.................... val.quot = numer / denom;
.................... val.rem = numer - (denom * val.quot);
.................... return (val);
.................... }
....................
.................... ldiv_t ldiv(signed long numer,signed long denom)
.................... {
.................... ldiv_t val;
.................... val.quot = numer / denom;
.................... val.rem = numer - (denom * val.quot);
.................... return (val);
.................... }
....................
.................... float atof(char * s)
.................... {
.................... float pow10 = 1.0;
.................... float result = 0.0;
.................... int sign = 0;
.................... char c;
.................... int ptr = 0;
....................
.................... c = s[ptr++];
....................
.................... if ((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
.................... if(c == '-') {
.................... sign = 1;
.................... c = s[ptr++];
.................... }
.................... if(c == '+')
.................... c = s[ptr++];
....................
.................... while((c >= '0' && c <= '9')) {
.................... result = 10*result + c - '0';
.................... c = s[ptr++];
.................... }
....................
.................... if (c == '.') {
.................... c = s[ptr++];
.................... while((c >= '0' && c <= '9')) {
.................... pow10 = pow10*10;
.................... result += (c - '0')/pow10;
.................... c = s[ptr++];
.................... }
.................... }
....................
.................... }
....................
.................... if (sign == 1)
.................... result = -1*result;
.................... return(result);
.................... }
....................
.................... float atoe(char * s)
.................... {
.................... float pow10 = 1.0;
.................... float result = 0.0;
.................... int sign = 0;
.................... int expsign = 0;
.................... char c;
.................... int ptr = 0;
.................... int i;
.................... float exp = 1.0;
.................... int expcnt = 0;
....................
.................... c = s[ptr++];
....................
.................... if ((c>='0' && c<='9') || c=='+' || c=='-' || c=='.' || c=='E' || c=='e') {
.................... if(c == '-') {
.................... sign = 1;
.................... c = s[ptr++];
.................... }
.................... if(c == '+')
.................... c = s[ptr++];
....................
.................... while((c >= '0' && c <= '9')) {
.................... result = 10*result + c - '0';
.................... c = s[ptr++];
.................... }
....................
.................... if (c == '.') {
.................... c = s[ptr++];
.................... while((c >= '0' && c <= '9')) {
.................... pow10 = pow10*10;
.................... result += (c - '0')/pow10;
.................... c = s[ptr++];
.................... }
.................... }
....................
.................... // Handling the exponent
.................... if (c=='e' || c=='E') {
.................... c = s[ptr++];
....................
.................... if(c == '-') {
.................... expsign = 1;
.................... c = s[ptr++];
.................... }
.................... if(c == '+')
.................... c = s[ptr++];
....................
.................... while((c >= '0' && c <= '9')) {
.................... expcnt = 10*expcnt + c - '0';
.................... c = s[ptr++];
.................... }
....................
.................... for(i=0;i<expcnt;i++)
.................... exp*=10;
....................
.................... if(expsign==1)
.................... result/=exp;
.................... else
.................... result*=exp;
.................... }
.................... }
....................
.................... if (sign == 1)
.................... result = -1*result;
.................... return(result);
.................... }
....................
.................... signed int atoi(char *s)
.................... {
.................... signed int result;
.................... int sign, base, index;
.................... char c;
....................
.................... index = 0;
.................... sign = 0;
.................... base = 10;
.................... result = 0;
....................
.................... if (!s)
.................... return 0;
.................... // Omit all preceeding alpha characters
.................... c = s[index++];
....................
.................... // increase index if either positive or negative sign is detected
.................... if (c == '-')
.................... {
.................... sign = 1; // Set the sign to negative
.................... c = s[index++];
.................... }
.................... else if (c == '+')
.................... {
.................... c = s[index++];
.................... }
....................
.................... if (c >= '0' && c <= '9')
.................... {
....................
.................... // Check for hexa number
.................... if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
.................... {
.................... base = 16;
.................... index++;
.................... c = s[index++];
.................... }
....................
.................... // The number is a decimal number
.................... if (base == 10)
.................... {
.................... while (c >= '0' && c <= '9')
.................... {
.................... result = 10*result + (c - '0');
.................... c = s[index++];
.................... }
.................... }
.................... else if (base == 16) // The number is a hexa number
.................... {
.................... c = toupper(c);
.................... while ( (c >= '0' && c <= '9') || (c >= 'A' && c<='F'))
.................... {
.................... if (c >= '0' && c <= '9')
.................... result = (result << 4) + (c - '0');
.................... else
.................... result = (result << 4) + (c - 'A' + 10);
....................
.................... c = s[index++];
.................... c = toupper(c);
.................... }
.................... }
.................... }
....................
.................... if (sign == 1 && base == 10)
.................... result = -result;
....................
.................... return(result);
.................... }
....................
.................... signed long atol(char *s)
.................... {
.................... signed long result;
.................... int sign, base, index;
.................... char c;
....................
.................... index = 0;
*
0226: CLRF xD0
.................... sign = 0;
0228: CLRF xCE
.................... base = 10;
022A: MOVLW 0A
022C: MOVWF xCF
.................... result = 0;
022E: CLRF xCD
0230: CLRF xCC
....................
.................... if (!s)
0232: MOVF xCA,W
0234: IORWF xCB,W
0236: BNZ 0240
.................... return 0;
0238: MOVLW 00
023A: MOVWF 01
023C: MOVWF 02
023E: BRA 0404
.................... c = s[index++];
0240: MOVF xD0,W
0242: INCF xD0,F
0244: CLRF 03
0246: ADDWF xCA,W
0248: MOVWF FE9
024A: MOVF xCB,W
024C: ADDWFC 03,W
024E: MOVWF FEA
0250: MOVFF FEF,D1
....................
.................... // increase index if either positive or negative sign is detected
.................... if (c == '-')
0254: MOVF xD1,W
0256: SUBLW 2D
0258: BNZ 0274
.................... {
.................... sign = 1; // Set the sign to negative
025A: MOVLW 01
025C: MOVWF xCE
.................... c = s[index++];
025E: MOVF xD0,W
0260: INCF xD0,F
0262: CLRF 03
0264: ADDWF xCA,W
0266: MOVWF FE9
0268: MOVF xCB,W
026A: ADDWFC 03,W
026C: MOVWF FEA
026E: MOVFF FEF,D1
.................... }
.................... else if (c == '+')
0272: BRA 028E
0274: MOVF xD1,W
0276: SUBLW 2B
0278: BNZ 028E
.................... {
.................... c = s[index++];
027A: MOVF xD0,W
027C: INCF xD0,F
027E: CLRF 03
0280: ADDWF xCA,W
0282: MOVWF FE9
0284: MOVF xCB,W
0286: ADDWFC 03,W
0288: MOVWF FEA
028A: MOVFF FEF,D1
.................... }
....................
.................... if (c >= '0' && c <= '9')
028E: MOVF xD1,W
0290: SUBLW 2F
0292: BTFSC FD8.0
0294: BRA 03E8
0296: MOVF xD1,W
0298: SUBLW 39
029A: BTFSS FD8.0
029C: BRA 03E8
.................... {
.................... if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
029E: MOVF xD1,W
02A0: SUBLW 30
02A2: BNZ 02E6
02A4: CLRF 03
02A6: MOVF xD0,W
02A8: ADDWF xCA,W
02AA: MOVWF FE9
02AC: MOVF xCB,W
02AE: ADDWFC 03,W
02B0: MOVWF FEA
02B2: MOVF FEF,W
02B4: SUBLW 78
02B6: BZ 02CC
02B8: CLRF 03
02BA: MOVF xD0,W
02BC: ADDWF xCA,W
02BE: MOVWF FE9
02C0: MOVF xCB,W
02C2: ADDWFC 03,W
02C4: MOVWF FEA
02C6: MOVF FEF,W
02C8: SUBLW 58
02CA: BNZ 02E6
.................... {
.................... base = 16;
02CC: MOVLW 10
02CE: MOVWF xCF
.................... index++;
02D0: INCF xD0,F
.................... c = s[index++];
02D2: MOVF xD0,W
02D4: INCF xD0,F
02D6: CLRF 03
02D8: ADDWF xCA,W
02DA: MOVWF FE9
02DC: MOVF xCB,W
02DE: ADDWFC 03,W
02E0: MOVWF FEA
02E2: MOVFF FEF,D1
.................... }
....................
.................... // The number is a decimal number
.................... if (base == 10)
02E6: MOVF xCF,W
02E8: SUBLW 0A
02EA: BNZ 032E
.................... {
.................... while (c >= '0' && c <= '9')
.................... {
02EC: MOVF xD1,W
02EE: SUBLW 2F
02F0: BC 032C
02F2: MOVF xD1,W
02F4: SUBLW 39
02F6: BNC 032C
.................... result = 10*result + (c - '0');
02F8: CLRF xD3
02FA: MOVLW 0A
02FC: MOVWF xD2
02FE: MOVFF CD,D5
0302: MOVFF CC,D4
0306: BRA 0206
0308: MOVLW 30
030A: SUBWF xD1,W
030C: ADDWF 01,W
030E: MOVWF xCC
0310: MOVLW 00
0312: ADDWFC 02,W
0314: MOVWF xCD
.................... c = s[index++];
0316: MOVF xD0,W
0318: INCF xD0,F
031A: CLRF 03
031C: ADDWF xCA,W
031E: MOVWF FE9
0320: MOVF xCB,W
0322: ADDWFC 03,W
0324: MOVWF FEA
0326: MOVFF FEF,D1
.................... }
032A: BRA 02EC
.................... }
.................... else if (base == 16) // The number is a hexa number
032C: BRA 03E8
032E: MOVF xCF,W
0330: SUBLW 10
0332: BNZ 03E8
.................... {
.................... c = toupper(c);
0334: MOVF xD1,W
0336: SUBLW 60
0338: BC 0346
033A: MOVF xD1,W
033C: SUBLW 7A
033E: BNC 0346
0340: MOVF xD1,W
0342: ANDLW DF
0344: BRA 0348
0346: MOVF xD1,W
0348: MOVWF xD1
.................... while ( (c >= '0' && c <= '9') || (c >= 'A' && c <='F'))
.................... {
034A: MOVF xD1,W
034C: SUBLW 2F
034E: BC 0356
0350: MOVF xD1,W
0352: SUBLW 39
0354: BC 0362
0356: MOVF xD1,W
0358: SUBLW 40
035A: BC 03E8
035C: MOVF xD1,W
035E: SUBLW 46
0360: BNC 03E8
.................... if (c >= '0' && c <= '9')
0362: MOVF xD1,W
0364: SUBLW 2F
0366: BC 0396
0368: MOVF xD1,W
036A: SUBLW 39
036C: BNC 0396
.................... result = (result << 4) + (c - '0');
036E: RLCF xCC,W
0370: MOVWF xD2
0372: RLCF xCD,W
0374: MOVWF xD3
0376: RLCF xD2,F
0378: RLCF xD3,F
037A: RLCF xD2,F
037C: RLCF xD3,F
037E: RLCF xD2,F
0380: RLCF xD3,F
0382: MOVLW F0
0384: ANDWF xD2,F
0386: MOVLW 30
0388: SUBWF xD1,W
038A: ADDWF xD2,W
038C: MOVWF xCC
038E: MOVLW 00
0390: ADDWFC xD3,W
0392: MOVWF xCD
.................... else
0394: BRA 03BE
.................... result = (result << 4) + (c - 'A' + 10);
0396: RLCF xCC,W
0398: MOVWF xD2
039A: RLCF xCD,W
039C: MOVWF xD3
039E: RLCF xD2,F
03A0: RLCF xD3,F
03A2: RLCF xD2,F
03A4: RLCF xD3,F
03A6: RLCF xD2,F
03A8: RLCF xD3,F
03AA: MOVLW F0
03AC: ANDWF xD2,F
03AE: MOVLW 41
03B0: SUBWF xD1,W
03B2: ADDLW 0A
03B4: ADDWF xD2,W
03B6: MOVWF xCC
03B8: MOVLW 00
03BA: ADDWFC xD3,W
03BC: MOVWF xCD
....................
.................... c = s[index++];c = toupper(c);
03BE: MOVF xD0,W
03C0: INCF xD0,F
03C2: CLRF 03
03C4: ADDWF xCA,W
03C6: MOVWF FE9
03C8: MOVF xCB,W
03CA: ADDWFC 03,W
03CC: MOVWF FEA
03CE: MOVF FEF,W
03D0: MOVWF xD1
03D2: SUBLW 60
03D4: BC 03E2
03D6: MOVF xD1,W
03D8: SUBLW 7A
03DA: BNC 03E2
03DC: MOVF xD1,W
03DE: ANDLW DF
03E0: BRA 03E4
03E2: MOVF xD1,W
03E4: MOVWF xD1
.................... }
03E6: BRA 034A
.................... }
.................... }
....................
.................... if (base == 10 && sign == 1)
03E8: MOVF xCF,W
03EA: SUBLW 0A
03EC: BNZ 03FC
03EE: DECFSZ xCE,W
03F0: BRA 03FC
.................... result = -result;
03F2: COMF xCC,F
03F4: COMF xCD,F
03F6: INCF xCC,F
03F8: BTFSC FD8.2
03FA: INCF xCD,F
....................
.................... return(result);
03FC: MOVFF CC,01
0400: MOVFF CD,02
.................... }
0404: RETLW 00
....................
.................... /* A fast routine to multiply by 10
.................... */
.................... signed int32 mult_with10(int32 num)
.................... {
.................... return ( (num << 1) + (num << 3) );
.................... }
....................
.................... signed int32 atoi32(char *s)
.................... {
.................... signed int32 result;
.................... int sign, base, index;
.................... char c;
....................
.................... index = 0;
.................... sign = 0;
.................... base = 10;
.................... result = 0;
....................
.................... if (!s)
.................... return 0;
.................... c = s[index++];
....................
.................... // increase index if either positive or negative sign is detected
.................... if (c == '-')
.................... {
.................... sign = 1; // Set the sign to negative
.................... c = s[index++];
.................... }
.................... else if (c == '+')
.................... {
.................... c = s[index++];
.................... }
....................
.................... if (c >= '0' && c <= '9')
.................... {
.................... if (c == '0' && (s[index] == 'x' || s[index] == 'X'))
.................... {
.................... base = 16;
.................... index++;
.................... c = s[index++];
.................... }
....................
.................... // The number is a decimal number
.................... if (base == 10)
.................... {
.................... while (c >= '0' && c <= '9') {
.................... result = (result << 1) + (result << 3); // result *= 10;
.................... result += (c - '0');
.................... c = s[index++];
.................... }
.................... }
.................... else if (base == 16) // The number is a hexa number
.................... {
.................... c = toupper(c);
.................... while ((c >= '0' && c <= '9') || (c >= 'A' && c <='F'))
.................... {
.................... if (c >= '0' && c <= '9')
.................... result = (result << 4) + (c - '0');
.................... else
.................... result = (result << 4) + (c - 'A' + 10);
....................
.................... c = s[index++];c = toupper(c);
.................... }
.................... }
.................... }
....................
.................... if (base == 10 && sign == 1)
.................... result = -result;
....................
.................... return(result);
.................... }
....................
.................... char * itoa(signed int32 num, int8 base, char *s)
.................... {
.................... int32 temp=1;
.................... int8 i,sign=0,cnt=0;
.................... char c;
....................
.................... if(num<0) {
.................... sign=1; // Check for negative number
.................... num*=-1;
.................... }
....................
.................... while(temp>0) {
.................... temp=(num/base);
.................... s[cnt]=(num%base)+'0'; // Conversion
....................
.................... if(s[cnt]>0x39)
.................... s[cnt]+=0x7;
....................
.................... cnt++;
.................... num=temp;
.................... }
....................
.................... if(sign==1) {
.................... s[cnt]=0x2D; // Negative sign
.................... cnt++;
.................... }
....................
.................... for(i = 0;i<(int8)(cnt/2);i++) {
....................
.................... c=s[i];
.................... s[i]=s[cnt-i-1]; // Reverse the number
.................... s[cnt-i-1]=c;
.................... }
.................... s[cnt]='\0'; // End the string
.................... return s;
.................... }
....................
.................... float strtod(char *s,char *endptr) {
.................... float pow10 = 1.0;
.................... float result = 0.0;
.................... int sign = 0, point = 0;
.................... char c;
.................... int ptr = 0;
....................
.................... if (!s)
.................... return 0;
.................... c=s[ptr++];
....................
....................
.................... while((c>='0' && c<='9') || c=='+' || c=='-' || c=='.') {
.................... if(c == '-') {
.................... sign = 1;
.................... c = s[ptr++];
.................... }
....................
.................... while((c >= '0' && c <= '9') && point == 0) {
.................... result = 10*result + c - '0';
.................... c = s[ptr++];
.................... }
....................
.................... if (c == '.') {
.................... point = 1;
.................... c = s[ptr++];
.................... }
....................
.................... while((c >= '0' && c <= '9') && point == 1) {
.................... pow10 = pow10*10;
.................... result += (c - '0')/pow10;
.................... c = s[ptr++];
.................... }
....................
.................... if (c == '+') {
.................... c = s[ptr++];
.................... }
.................... }
....................
.................... if (sign == 1)
.................... result = -1*result;
.................... if(endptr)
.................... {
.................... if (ptr) {
.................... ptr--;
.................... *((char *)endptr)=s+ptr;
.................... }
.................... else
.................... *((char *)endptr)=s;
.................... }
....................
.................... return(result);
.................... }
....................
.................... long strtoul(char *s,char *endptr,signed int base)
.................... {
.................... char *sc,*s1,*sd;
.................... unsigned long x=0;
.................... char sign;
.................... char digits[]="0123456789abcdefghijklmnopqstuvwxyz";
.................... for(sc=s;isspace(*sc);++sc);
.................... sign=*sc=='-'||*sc=='+'?sc++:'+';
.................... if(sign=='-')
.................... {
.................... if (endptr)
.................... {
.................... *((char *)endptr)=s;
.................... }
.................... return 0;
.................... }
....................
.................... if (base <0 || base ==1|| base >36) // invalid base
.................... {
.................... if (endptr)
.................... {
.................... *((char *)endptr)=s;
.................... }
.................... return 0;
.................... }
.................... else if (base)
.................... {
.................... if(base==16 && *sc =='0'&&(sc[1]=='x' || sc[1]=='X'))
.................... sc+=2;
.................... if(base==8 && *sc =='0')
.................... sc+=1;
.................... if(base==2 && *sc =='0'&&sc[1]=='b')
.................... sc+=2;
....................
.................... }
.................... else if(*sc!='0') // base is 0, find base
.................... base=10;
.................... else if (sc[1]=='x' || sc[1]=='X')
.................... base =16,sc+=2;
.................... else if(sc[1]=='b')
.................... base=2,sc+=2;
.................... else
.................... base=8;
.................... for (s1=sc;*sc=='0';++sc);// skip leading zeroes
.................... sd=memchr(digits,tolower(*sc),base);
.................... for(; sd!=0; )
.................... {
.................... x=x*base+(int16)(sd-digits);
.................... ++sc;
.................... sd=memchr(digits,tolower(*sc),base);
.................... }
.................... if(s1==sc)
.................... {
.................... if (endptr)
.................... {
.................... *((char *)endptr)=s;
.................... }
.................... return 0;
.................... }
.................... if (endptr)
.................... *((char *)endptr)=sc;
.................... return x;
.................... }
....................
....................
.................... signed long strtol(char *s,char *endptr,signed i |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Aug 16, 2005 8:48 pm |
|
|
Because you posted so much code, I think the forum software cut it off
after a certain point. The code that you posted consists mostly of
string.h and stdlib.h which are not what I wanted to see.
Can you edit your post and delete out all that stuff and just post
the #int_ssp code, and any other i2c code ? That way, it would
shorten the post down to essentials and also not take up so much space. |
|
|
Guest
|
|
Posted: Wed Aug 17, 2005 6:51 am |
|
|
Here are some excerts in order of how they appear from my code. sorry about the last post. I have an interrupt routine for int_ssp that calls my own interrupt handler (i2c_interrupt_handler()).. I also tried to output a "0" to pin a2 to know if i ever even made it to the SSP_isr() which never happened. So the problem lies even before my call to the interrupt handler that is supposed to deal with the i2c.. it doesnt even interrupt!
Thanks
.................... #INT_SSP
.................... SSP_isr()
.................... {
.................... output_bit(pin_a2,0);
*
01FA: BCF F89.2
01FC: BCF F92.2
.................... i2c_interrupt_handler();
01FE: BRA 0116
.................... }
.
.
.
.
.................... ///////////////////////////////////////////////////////////////////
.................... //Main Method
.................... ///////////////////////////////////////////////////////////////////
.................... void main()
.................... {
*
12D6: CLRF FF8
12D8: BCF FD0.7
12DA: BSF 0D.7
12DC: CLRF FEA
12DE: CLRF FE9
12E0: BCF FB9.0
12E2: BCF FC1.6
12E4: BCF FC1.7
12E6: MOVLW 00
12E8: MOVWF FB8
12EA: BSF FAA.3
12EC: MOVLW 56
12EE: MOVWF FAF
12F0: MOVLW 00
12F2: MOVWF FB0
12F4: MOVLW 26
12F6: MOVWF FAC
12F8: MOVLW 90
12FA: MOVWF FAB
12FC: BSF F94.5
12FE: BSF F94.4
1300: MOVLW 01
1302: MOVWF FC8 <-------- SSPADD recieving address of "1"
1304: MOVLW 36
1306: MOVWF FC6 <--------SSPCON recieving "00110110"
1308: CLRF 19 Which means "no collision, no overflow,
130A: CLRF 1A enable serial port, release clock (no stretch)
130C: MOVLW 01 and the mode is slave-7-bit addressing.
130E: MOVWF 1B
1310: CLRF 1C
1312: CLRF 1D
1314: CLRF 1E
1316: MOVLW FF
1318: MOVWF 42
131A: MOVLW 3F
131C: MOVWF 43
131E: MOVLW 01
1320: MOVWF 44
1322: MOVLW C0
1324: MOVWF 45
1326: CLRF 47
1328: CLRF 48
132A: CLRF 49
132C: CLRF 4A
132E: CLRF 4B
1330: CLRF 4C
1332: CLRF 4D
1334: CLRF 4E
1336: CLRF 4F
1338: CLRF 50
133A: CLRF 51
133C: CLRF 52
133E: CLRF 53
1340: CLRF 54
1342: CLRF 55
1344: CLRF 56
1346: CLRF 57
1348: CLRF 58
134A: CLRF 59
134C: CLRF 5A
134E: CLRF 5D
1350: BCF 46.1
1352: CLRF x90
1354: CLRF x91
1356: CLRF x92
1358: CLRF x93
135A: CLRF x94
135C: CLRF x95
135E: CLRF x96
1360: CLRF x97
1362: CLRF x98
1364: CLRF x99
1366: CLRF x9A
1368: CLRF x9B
.
.
.
.
.
.................... enable_interrupts(INT_SSP);
1434: BSF F9D.3
.................... enable_interrupts(GLOBAL);
1436: MOVLW C0
1438: IORWF FF2,F
.
.
.
.
.................... void i2c_interrupt_handler(void)
.................... {
....................
.................... unsigned char i2c_mask = 0x2D; /* 0010 1101 */
*
0116: MOVLW 2D
0118: MOVWF xC2
.................... unsigned char temp_sspstat;
.................... unsigned char this_byte;
.................... unsigned char tx_byte;
.................... int x;
....................
.................... output_bit(pin_a2,0);
011A: BCF F89.2
011C: BCF F92.2
.................... if(input(pin_c0)==1){
011E: BSF F94.0
0120: MOVLW 00
0122: BTFSC F82.0
0124: MOVLW 01
0126: SUBLW 01
0128: BNZ 0130
.................... output_bit(pin_c3,0);}
012A: BCF F8B.3
012C: BCF F94.3
.................... else{
012E: BRA 0134
.................... output_bit(pin_c0,1);}
0130: BSF F8B.0
0132: BCF F94.0
....................
.................... /* Mask out the unnecessary bits */
.................... temp_sspstat = PIC_SSPSTAT & i2c_mask;
0134: MOVF FC7,W
0136: ANDWF xC2,W
0138: MOVWF xC3
....................
.................... switch (temp_sspstat)
.................... {
013A: MOVF xC3,W
013C: XORLW 09
013E: BZ 0152
0140: XORLW 20
0142: BZ 017C
0144: XORLW 25
0146: BZ 01A4
0148: XORLW 20
014A: BZ 01C6
014C: XORLW 04
014E: BZ 01EE
0150: BRA 01F4
.................... /* Write operation, last byte was an address, buffer is full */
.................... case 0x09: /* 0000 1001 */
.................... /* Clear the receive buffer */
.................... for (x=0; x<RX_BUF_LEN; x++)
0152: CLRF xC6
0154: MOVF xC6,W
0156: SUBLW 1F
0158: BNC 016E
.................... {
.................... slave_buffer[x] = 0x00;
015A: CLRF 03
015C: MOVF xC6,W
015E: ADDLW 1F
0160: MOVWF FE9
0162: MOVLW 00
0164: ADDWFC 03,W
0166: MOVWF FEA
0168: CLRF FEF
.................... }
016A: INCF xC6,F
016C: BRA 0154
.................... buffer_index = 0; /* Clear the buffer index */
016E: CLRF 3F
.................... this_byte = read_i2c(); /* Do a dummy read of PIC_SSPBUF */
0170: RCALL 00CA
0172: MOVFF 01,C4
....................
.................... debug_state = 1;
0176: MOVLW 01
0178: MOVWF 41
.................... break;
017A: BRA 01F6
....................
.................... /* Write operation, last byte was data, buffer is full */
.................... case 0x29: /* 0010 1001 */
.................... /* Point to the buffer */
.................... this_byte = read_i2c(); /* Get the byte from the SSP */
017C: RCALL 00CA
017E: MOVFF 01,C4
.................... slave_buffer[buffer_index] = this_byte; /* Put it into the buffer */
0182: CLRF 03
0184: MOVF 3F,W
0186: ADDLW 1F
0188: MOVWF FE9
018A: MOVLW 00
018C: ADDWFC 03,W
018E: MOVWF FEA
0190: MOVFF C4,FEF
.................... buffer_index++; /* Increment the buffer pointer */
0194: INCF 3F,F
.................... /* Get the current buffer index */
.................... /* Subtract the buffer length */
.................... /* Has the index exceeded the buffer length?*/
.................... if (buffer_index >= RX_BUF_LEN)
0196: MOVF 3F,W
0198: SUBLW 1F
019A: BC 019E
.................... {
.................... buffer_index = 0; /* Yes, clear the buffer index. */
019C: CLRF 3F
.................... }
.................... debug_state = 2;
019E: MOVLW 02
01A0: MOVWF 41
.................... break;
01A2: BRA 01F6
....................
.................... /* Read operation; last byte was an address, buffer is empty */
.................... case 0x0C: /* 0000 1100 */
.................... buffer_index = 0; /* Clear the buffer index */
01A4: CLRF 3F
.................... /* Point to the buffer */
.................... tx_byte = slave_buffer[buffer_index]; /* Get byte from the buffer */
01A6: CLRF 03
01A8: MOVF 3F,W
01AA: ADDLW 1F
01AC: MOVWF FE9
01AE: MOVLW 00
01B0: ADDWFC 03,W
01B2: MOVWF FEA
01B4: MOVFF FEF,C5
.................... write_i2c(3); /* Write the byte to PIC_SSPBUF */
01B8: MOVLW 03
01BA: MOVWF xC7
01BC: RCALL 00D0
.................... buffer_index++; /* increment the buffer index */
01BE: INCF 3F,F
.................... debug_state = 3;
01C0: MOVLW 03
01C2: MOVWF 41
.................... break;
01C4: BRA 01F6
....................
....................
.................... /* Read operation; last byte was data, buffer is empty */
.................... case 0x2C: /* 0010 1100 */
.................... /* Get the current buffer index */
.................... /* Subtract the buffer length */
.................... /* Has the index exceeded the buffer length?*/
.................... if (buffer_index >= RX_BUF_LEN)
01C6: MOVF 3F,W
01C8: SUBLW 1F
01CA: BC 01CE
.................... {
.................... buffer_index = 0; /* Yes, clear the buffer index */
01CC: CLRF 3F
.................... }
.................... /* Point to the buffer */
.................... /* Get the byte */
.................... tx_byte = slave_buffer[buffer_index];
01CE: CLRF 03
01D0: MOVF 3F,W
01D2: ADDLW 1F
01D4: MOVWF FE9
01D6: MOVLW 00
01D8: ADDWFC 03,W
01DA: MOVWF FEA
01DC: MOVFF FEF,C5
.................... write_i2c(3); /* Write to PIC_SSPBUF */
01E0: MOVLW 03
01E2: MOVWF xC7
01E4: RCALL 00D0
.................... buffer_index++; /* increment the buffer index */
01E6: INCF 3F,F
.................... debug_state = 4;
01E8: MOVLW 04
01EA: MOVWF 41
.................... break;
01EC: BRA 01F6
....................
.................... /* A NACK was received when transmitting data back from the master. */
.................... /* Slave logic is reset in this case. R_W=0, D_A=1, and BF=0. */
.................... /* If we don't stop in this state, then something is wrong!! */
.................... case 0x28: /* 0010 1000 */
.................... debug_state = 5;
01EE: MOVLW 05
01F0: MOVWF 41
.................... break;
01F2: BRA 01F6
....................
.................... /* Something went wrong!! */
.................... default:
.................... i2c_error();
01F4: BRA 00F6
.................... break;
.................... }
.................... }
01F6: GOTO 0200 (RETURN)
....................
.................... void i2c_error(void)
.................... {
.................... comms_error = 1;
*
00F6: MOVLW 01
00F8: MOVWF 40
.................... printf ("I2C ERROR!\r\n");
00FA: CLRF xC7
00FC: MOVF xC7,W
00FE: RCALL 00AC
0100: INCF xC7,F
0102: MOVWF 00
0104: MOVF 00,W
0106: BTFSS F9E.4
0108: BRA 0106
010A: MOVWF FAD
010C: MOVLW 0C
010E: SUBWF xC7,W
0110: BNZ 00FC
.................... }
0112: GOTO 01F6 (RETURN)
....................
.................... void write_i2c(unsigned char transmit_byte)
.................... {
.................... unsigned char write_collision = 1;
*
00D0: MOVLW 01
00D2: MOVWF xC8
....................
.................... while (PIC_SSPSTAT & PIC_SSPSTAT_BIT_BF) /* Is BF bit set in PIC_SSPSTAT?*/
.................... {
00D4: BTFSS FC7.0
00D6: BRA 00DA
.................... /* If yes, then keep waiting */
.................... }
00D8: BRA 00D4
....................
.................... while (write_collision)
.................... {
00DA: MOVF xC8,F
00DC: BZ 00F2
.................... /* If not, then do the i2c_write. */
.................... PIC_SSPCON1 &= ~PIC_SSPCON1_BIT_WCOL; /* Clear the WCOL flag */
00DE: BCF FC6.7
.................... PIC_SSPBUF = transmit_byte;
00E0: MOVFF C7,FC9
....................
.................... /* Was there a write collision?*/
.................... if (PIC_SSPCON1 & PIC_SSPCON1_BIT_WCOL)
00E4: BTFSS FC6.7
00E6: BRA 00EE
.................... {
.................... /* Yes there was a write collision. */
.................... write_collision = 1;
00E8: MOVLW 01
00EA: MOVWF xC8
.................... }
.................... else
00EC: BRA 00F0
.................... {
.................... /* NO, there was no write collision. */
.................... /* The transmission was successful */
.................... write_collision = 0;
00EE: CLRF xC8
.................... }
.................... }
00F0: BRA 00DA
.................... PIC_SSPCON1 |= PIC_SSPCON1_BIT_CKP; /* Release the clock. */
00F2: BSF FC6.4
.................... }
00F4: RETLW 00
....................
.................... /* This function returns the byte in SSPBUF */
.................... unsigned char read_i2c(void)
.................... {
.................... return PIC_SSPBUF;
*
00CA: MOVF FC9,W
00CC: MOVWF 01
.................... }
00CE: RETLW 00
....................
....................
.................... |
|
|
joshkeys
Joined: 16 Aug 2005 Posts: 37 Location: Fredericton,NB
|
I figured it out!! |
Posted: Wed Aug 17, 2005 10:07 am |
|
|
After grueling hours looking over my code, i saw that the statement Setup_SPI(False) overwrote the spcon and spadd with 0's.. man.. finally! It is interupting.. I am not sure if i have it totally working, but i do know that it is recognizing activity. i need to go back to my original code and try it now.. Thanks for your time
Josh |
|
|
|
|
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
|