// pass_i2c_tear.c /* Copyright (C) 2017 H.Poetzl ** ** This program is free software: you can redistribute it and/or ** modify it under the terms of the GNU General Public License ** as published by the Free Software Foundation, either version ** 2 of the License, or (at your option) any later version. */ // ------------------------------------------------ // configuration #define NO_BIT_DEFINES #include #include #include #define CONFIG(k, n) __code static char __at _ ## k __ ## k = n // CONFIG(CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT1 & _CSWEN_ON & _CLKOUTEN_OFF); CONFIG(CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CSWEN_ON & _CLKOUTEN_OFF); CONFIG(CONFIG2, _MCLRE_ON & _WDTE_OFF & _PPS1WAY_OFF); #define SCL_TRIS TRISAbits.TRISA0 #define SCL_RPPS RA0PPS #define SCL_PPS 0b11000 #define SCL_PPSP 0b00101 #define SDA_TRIS TRISAbits.TRISA5 #define SDA_RPPS RA5PPS #define SDA_PPS 0b11001 #define SDA_PPSP 0b00000 #define LED0L LATA #define LED0T TRISA #define LED0 2 #define LED1L LATC #define LED1T TRISC #define LED1 0 #define LED2L LATC #define LED2T TRISC #define LED2 1 #define LED3L LATC #define LED3T TRISC #define LED3 2 #define LED4L LATB #define LED4T TRISB #define LED4 4 #define LED5L LATB #define LED5T TRISB #define LED5 5 #define LED6L LATB #define LED6T TRISB #define LED6 6 #define LED7L LATB #define LED7T TRISB #define LED7 7 #define LED8L LATC #define LED8T TRISC #define LED8 7 #define LED9L LATC #define LED9T TRISC #define LED9 6 #define LEDAL LATC #define LEDAT TRISC #define LEDA 3 #define LEDBL LATC #define LEDBT TRISC #define LEDB 4 #define LEDCL LATC #define LEDCT TRISC #define LEDC 5 #define LEDDL LATA #define LEDDT TRISA #define LEDD 7 #define LEDEL LATA #define LEDET TRISA #define LEDE 7 #define LEDFL LATA #define LEDFT TRISA #define LEDF 7 void delay(uint8_t val) { val &= 0xFF; __asm NOP ; 1us delay loop DECFSZ WREG,W BRA $-2 __endasm; } void led_on(uint8_t id) { id &= 0xF; __asm ANDLW 0xF BANKSEL LATA BTFSC WREG,3 BRA _led_8_on_ ; 8-F BTFSC WREG,2 BRA _led_4_on_ ; 4-7 BTFSC WREG,1 BRA _led_2_on_ ; 2-3 BTFSC WREG,0 BRA _led_1_on_ ; 1 BCF LED0L,LED0 RETURN _led_8_on_: BTFSC WREG,2 BRA _led_C_on_ ; C-F BTFSC WREG,1 BRA _led_A_on_ ; A-B BTFSC WREG,0 BRA _led_9_on_ BCF LED8L,LED8 RETURN _led_4_on_: BTFSC WREG,1 BRA _led_6_on_ ; 6-7 BTFSC WREG,0 BRA _led_5_on_ BCF LED4L,LED4 RETURN _led_C_on_: BTFSC WREG,1 BRA _led_E_on_ ; E-F BTFSC WREG,0 BRA _led_D_on_ BCF LEDCL,LEDC RETURN _led_2_on_: BTFSC WREG,0 BRA _led_3_on_ BCF LED2L,LED2 RETURN _led_6_on_: BTFSC WREG,0 BRA _led_7_on_ BCF LED6L,LED6 RETURN _led_A_on_: BTFSC WREG,0 BRA _led_B_on_ BCF LEDAL,LEDA RETURN _led_E_on_: BTFSC WREG,0 BRA _led_F_on_ BCF LEDEL,LEDE RETURN _led_1_on_: BCF LED1L,LED1 RETURN _led_3_on_: BCF LED3L,LED3 RETURN _led_5_on_: BCF LED5L,LED5 RETURN _led_7_on_: BCF LED7L,LED7 RETURN _led_9_on_: BCF LED9L,LED9 RETURN _led_B_on_: BCF LEDBL,LEDB RETURN _led_D_on_: BCF LEDDL,LEDD RETURN _led_F_on_: BCF LEDFL,LEDF RETURN __endasm; } void led_off(uint8_t id) { id &= 0xF; __asm ANDLW 0xF BANKSEL LATA BTFSC WREG,3 BRA _led_8_off_ ; 8-F BTFSC WREG,2 BRA _led_4_off_ ; 4-7 BTFSC WREG,1 BRA _led_2_off_ ; 2-3 BTFSC WREG,0 BRA _led_1_off_ BSF LED0L,LED0 RETURN _led_8_off_: BTFSC WREG,2 BRA _led_C_off_ ; C-F BTFSC WREG,1 BRA _led_A_off_ ; A-B BTFSC WREG,0 BRA _led_9_off_ BSF LED8L,LED8 RETURN _led_4_off_: BTFSC WREG,1 BRA _led_6_off_ ; 6-7 BTFSC WREG,0 BRA _led_5_off_ BSF LED4L,LED4 RETURN _led_C_off_: BTFSC WREG,1 BRA _led_E_off_ ; E-F BTFSC WREG,0 BRA _led_D_off_ BSF LEDCL,LEDC RETURN _led_2_off_: BTFSC WREG,0 BRA _led_3_off_ BSF LED2L,LED2 RETURN _led_6_off_: BTFSC WREG,0 BRA _led_7_off_ BSF LED6L,LED6 RETURN _led_A_off_: BTFSC WREG,0 BRA _led_B_off_ BSF LEDAL,LEDA RETURN _led_E_off_: BTFSC WREG,0 BRA _led_F_off_ BSF LEDEL,LEDE RETURN _led_1_off_: BSF LED1L,LED1 RETURN _led_3_off_: BSF LED3L,LED3 RETURN _led_5_off_: BSF LED5L,LED5 RETURN _led_7_off_: BSF LED7L,LED7 RETURN _led_9_off_: BSF LED9L,LED9 RETURN _led_B_off_: BSF LEDBL,LEDB RETURN _led_D_off_: BSF LEDDL,LEDD RETURN _led_F_off_: BSF LEDFL,LEDF RETURN __endasm; } // -------------------------------------------------- // and our main entry point void main() { uint16_t cnt = 0; bool tgl = false; // all digital ANSELA = 0; ANSELB = 0; ANSELC = 0; // all input TRISA = 0xFF; TRISB = 0xFF; TRISC = 0xFF; // all open drain ODCONA = 0xFF; ODCONB = 0xFF; ODCONC = 0xFF; // all output high LATA = 0xFF; LATB = 0xFF; LATC = 0xFF; __asm BANKSEL TRISA BCF LED0T,LED0 BCF LED1T,LED1 BCF LED2T,LED2 BCF LED3T,LED3 BCF LED4T,LED4 BCF LED5T,LED5 BCF LED6T,LED6 BCF LED7T,LED7 BCF LED8T,LED8 BCF LED9T,LED9 BCF LEDAT,LEDA BCF LEDBT,LEDB BCF LEDCT,LEDC __endasm; // set i2c pins to input SCL_TRIS = 1; SDA_TRIS = 1; PPSLOCKbits.PPSLOCKED = 0; SSP1DATPPS = SDA_PPSP; SDA_RPPS = SDA_PPS; SSP1CLKPPS = SCL_PPSP; SCL_RPPS = SCL_PPS; SSPADD = 0x4F; SSP1STAT = 0; SSP1STATbits.SMP = 1; SSP1STATbits.CKE = 1; SSP1CON1 = 0; SSP1CON1bits.SSPM = 0b1000; /* I2C master mode */ SSP1CON1bits.SSPEN = 1; /* enable I2C */ // SSP1CON1bits.CKP = 1; /* enable I2C clock */ SSP1CON2 = 0; // SSP1CON2bits.SEN = 0; /* clock stretching disabled */ SSP1CON3 = 0; // SSP1CON3bits.BOEN = 1; /* buffer override enabled */ while (1) { uint8_t bit; for (bit=0; bit<6; bit++) led_off(bit); while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) led_on(0); SSP1CON2bits.SEN = 1; /* generate start */ while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) led_on(1); SSP1BUF = (0x1D << 1) | 1; /* slave address */ while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) led_on(2); SSP1CON2bits.RCEN = 1; /* receive */ while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) led_on(3); cnt = SSP1BUF; while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) led_on(4); SSP1CON2bits.ACKDT = 0; SSP1CON2bits.ACKEN = 1; while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) led_on(5); SSP1CON2bits.PEN = 1; /* generate end */ while ((SSP1CON2 & 0x1F) || (SSP1STAT & 0x4)) #if 0 SSP1BUF = (0x1D << 1); /* slave address */ while (!PIR1bits.SSP1IF); /* wait for completion */ PIR1bits.SSP1IF = 0; /* clear SSP1IF */ SSP1CON2bits.RCEN = 1; /* generate start */ while (!PIR1bits.SSP1IF); /* wait for completion */ PIR1bits.SSP1IF = 0; /* clear SSP1IF */ #endif for (bit=0; bit<8; bit++) { if ((cnt >> bit) & 1) led_on(bit + 6); else led_off(bit + 6); } delay(16); for (bit=0; bit<8; bit++) led_off(bit + 6); delay(255); cnt++; } }