Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /** C O N F I G U R A T I O N B I T S ******************************/
- #pragma config FOSC = INTIO67, FCMEN = OFF, IESO = OFF // CONFIG1H
- #pragma config PWRT = OFF, BOREN = SBORDIS, BORV = 30 // CONFIG2L
- #pragma config WDTEN = OFF, WDTPS = 32768 // CONFIG2H
- #pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = ON, CCP2MX = PORTC // CONFIG3H
- #pragma config STVREN = ON, LVP = OFF, XINST = OFF // CONFIG4L
- #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF // CONFIG5L
- #pragma config CPB = OFF, CPD = OFF // CONFIG5H
- #pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF // CONFIG6L
- #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF // CONFIG6H
- #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTR3 = OFF // CONFIG7L
- #pragma config EBTRB = OFF // CONFIG7H
- /** I N C L U D E S **************************************************/
- #include "p18f46k20.h"
- #include "delays.h"
- #include "usart.h"
- //OLED crap
- #include "stdio.h"
- #include "OLED/oled_interface.h"
- #include "OLED/oled_jib.h"
- #include "OLED/oled_cmd.h"
- /** V A R I A B L E S *************************************************/
- #pragma udata // declare statically allocated uinitialized variables
- volatile unsigned long int tick = 0;
- volatile unsigned char timer0intflag = 0;
- volatile unsigned char last_ADC_val = 0;
- char sendbuffer[127] = "Hello world";
- /** D E C L A R A T I O N S *******************************************/
- // declare constant data in program memory starting at address 0x180
- const rom unsigned char sinevals[128] = {
- 32,33,35,36,38,39,41,42,44,45,47,48,49,51,52,53,
- 54,55,56,57,58,59,60,60,61,62,62,62,63,63,63,63,
- 63,63,63,63,63,62,62,62,61,60,60,59,58,57,56,55,
- 54,53,52,51,49,48,47,45,44,42,41,39,38,36,35,33,
- 32,30,28,27,25,24,22,21,19,18,16,15,14,12,11,10,
- 9, 8, 7, 6, 5, 4, 3, 3, 2, 1, 1, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 3, 4, 5, 6, 7, 8,
- 9,10,11,12,14,15,16,18,19,21,22,24,25,27,28,30};
- unsigned char ADC_GetConv(void);
- void ADC_StartConv(void);
- #pragma interruptlow InterruptServiceLow// "interruptlow" pragma for low priority
- void InterruptServiceLow(void) {
- //This interrupt takes 25 instructions (approx 25 cycles = 1.6us @ 64MHz=16MIPS)
- //Happens every 16us (1/(16MHz/256)), uses about 1.6us/16us = 10% of CPU time
- //Interrupt frequency: 62.5kHz
- LATD |= 0b00000001;
- if (INTCON & 0b00000100) { //TIMER0 Interrupt
- INTCON &= 0b11111011; //CLEAR Timer0 interrupt flag
- tick++;
- last_ADC_val = ADRESH;
- ADCON0 |= (1<<1);;
- timer0intflag = 1;
- }
- LATD &= 0b11111110;
- }
- //----------------------------------------------------------------------------
- // High priority interrupt vector
- /*#pragma code InterruptVectorHigh = 0x08
- void InterruptVectorHigh (void) // NOT USED ATM
- {
- _asm
- goto InterruptServiceHigh //jump to interrupt routine
- _endasm
- }*/
- //----------------------------------------------------------------------------
- // Low priority interrupt vector
- #pragma code InterruptVectorLow = 0x18
- void InterruptVectorLow (void) {
- _asm
- goto InterruptServiceLow //jump to interrupt routine
- _endasm
- }
- #pragma code // declare executable instructions
- typedef struct {
- unsigned char frequency;
- unsigned char amplitude;
- char phase;
- } wave;
- typedef struct {
- wave low;
- wave high;
- unsigned int duration;
- } modulation;
- void setup(void) {
- //////// PORT SETUP ////////
- TRISC = 0b00000000; //All PORTC pins are OUTPUTS
- LATC = 0b00101000; //All PORTC pins are HIGH
- TRISD = 0b00000000; //All PORTC pins are OUTPUTS (LEDs 0 to 7)
- LATD = 0b00100000; //All PORTC pins are (LED 5 is HIGH (PWM))
- TRISE = 0b00000111; // Needed for OLED Display
- TRISA = 0;
- LATA = 0b11110000; //Needed for OLED Display ( Don't use 1st bit) -TRIS A defined in adc_init
- TRISB = 0b00001111; // All switches are inputs 0-3
- ANSELH = 0x00; // RB0 - RB4 Digital input
- WPUB = 0b11111111; //PULL UP PULL UP
- //////// SYSTEM CLOCK to 64MHz //////// (Initially FOSC = 1MHz)
- OSCCON = 0b01110000; //Clock = 16MHz (=FOSC), (internal oscillator, full speed)
- OSCTUNE |= 0b01000000; //Clock = 64MHz (=FOSC*4), (PLL enable bit set )
- //////// PWM SETUP ////////
- PR2 = 0b00001111; //Timer2 period = 15
- CCPR1L = 0b00000000; //Duty cycle 8 HIGH bits CLEARED
- CCP1CON = 0b00001100; //SINGLE OUTPUT mode, Duty cycle 2 LOW bits CLEARED, PWM pins are LOW, PWM MODE, ACTIVE HIGH
- T2CON = 0b00000100; //Timer 2 ENABLED, PRESCALER = 1:1, POSTSCALER: 1:1
- PSTRCON = 0b00000011; //PWM PULSE STEERING: PWM routed to P1A (RC2) and P1B (RD5, LED5)
- //////// TIMER0 INTERRUPT SETUP ////////
- RCON |= 0b10000000; //Interrupt Priority Levels ENABLED (IPEN bit set)
- INTCON = 0b11100000; //Global Interrupt L&H ENABLE, Timer0 int. ENABLE, other interrupts DISABLED, flags CLEARED
- INTCON2 = 0b00000000; //Timer0 Interrupt is LOW priority
- TMR0H = 0b00000000; //Clear timer - always write upper byte first
- TMR0L = 0b00000000;
- T0CON = 0b11001000; //Timer ENABLED, 8-BIT mode, clock source is FOSC (16MHz), NO PRESCALER
- //T0CON = 0b10001000; // ! ! ! 16-BIT MODE ! ! !
- LATD |= 0b10000000; //Turn LED 7 ON to indicate program execution
- //We have 8 LEDs on the board, we might as well use them.
- // Configure MSSP for SPI master mode
- SSPCON1 = 0b00110010; // clock idle high, Clk /64
- SSPSTAT = 0b00000000;
- oled_res = 1; // do not reset LCD yet
- oled_cs = 1; // do not select the LCD
- INTCONbits.PEIE = 1;
- //INTCONbits.GIE = 1;
- }
- void pwm(unsigned char level) {
- CCP1CON &= 0b11001111; //Clear 2 LSBs
- CCP1CON |= ((level & 0b00000011)<<4); //Set 2 LSBs
- CCPR1L = 0b00001111 & (level>>2); //Write 4 MSBs
- return;
- }
- void sine(wave wav, unsigned int duration) {
- int i = 0;
- int j = wav.phase;
- int nextpwm;
- for (i=0; i<duration; i++) {
- nextpwm = (wav.amplitude!=0)?sinevals[j]:32;
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- pwm(nextpwm); //Next pwm
- j+=wav.frequency;
- j &= 127;
- }
- }
- /*void sendbyte(unsigned char byteToSend, modulation mod) {
- unsigned char bitno;
- sine(mod.low, mod.duration); //Start bit
- for (bitno=0; bitno<8; bitno++) { //Send 8 bit,s LSB first
- sine(((byteToSend&(1<<bitno))?mod.high:mod.low), mod.duration);
- }
- sine(mod.high, mod.duration); //Two stop bits
- sine(mod.high, mod.duration);
- }*/
- void sendbyte(unsigned char byteToSend, modulation mod) {
- unsigned char bitno;
- sine(mod.low, mod.duration); //Two stop bits
- sine(mod.low, mod.duration);
- sine(mod.high, mod.duration);
- for (bitno=0; bitno<8; bitno++) { //Send 8 bit,s LSB first
- sine(((byteToSend&(1<<bitno))?mod.high:mod.low), mod.duration);
- }
- sine(mod.low, mod.duration); //Two stop bits
- sine(mod.low, mod.duration);
- }
- void sendstring(char* charptr, modulation mod) {
- while (*charptr != 0) {
- sendbyte(*charptr, mod);
- charptr++;
- }
- sendbyte(0x00, mod);
- LATD |= 0b00000001;
- }
- void UART_ArraySend(char *array)
- {
- int i=0;
- while(*(array+i)!=0) {
- WriteUSART(array[i]);
- while(!(TXSTA & 0b10));
- i++;
- }
- }
- //////// ADC functions ////////
- void ADC_Init(void){
- //Configure Inputs
- TRISA |= 0x01;
- ANSEL |= 0x01;
- ADCON0 = (1<<0) | (0<<2); //Enable ADC and select channel 0
- ADCON1 = (0<<4) | (0<<5); //Set both references to PIC supply
- ADCON2 = (4<<0) | (7<<3) | (0<<7); //Use 20 acquisition cycles and FOsc/4, left justified
- }
- void ADC_StartConv(void){
- ADCON0 |= (1<<1);
- }
- unsigned int ADC_CheckConv(void){
- if(ADCON0 & 2) return 1;
- else return 0;
- }
- void ADC_WaitForConv(void){
- while(ADC_CheckConv());
- }
- unsigned char ADC_GetConv(void){
- return ADRESH;
- }
- //////// Demodulation //////
- unsigned char demodulate(modulation mod) {
- unsigned long int startTick = 0;
- unsigned int freq = 0;
- unsigned char prev_ADRESH = 0;
- unsigned int tresholdfreq = ((mod.high.frequency)*(mod.duration/128) + (mod.low.frequency)*(mod.duration/128)) / 2;
- unsigned char received_data = 0b00000000;
- unsigned char bit_no;
- unsigned long int lastZero = tick; //This used to be a CHAR because I'm retarded
- unsigned int lastPeriod = 0;
- /*while(lastPeriod > tresholdfreq && startTick > 8) {
- while(!(timer0intflag)); //wait for interrupt to happen
- timer0intflag = 0; //Reset interrupt flag
- if (ADRESH > 127 && prev_ADRESH <= 127) {
- lastPeriod = tick - lastZero;
- }
- startTick++;
- }
- startTick = tick;
- while(tick > startTick + mod.duration);*/
- while(!(timer0intflag));
- timer0intflag = 0;
- for (bit_no = 0; bit_no < 8; bit_no++) {
- startTick = tick;
- freq=0;
- while (tick < (startTick + mod.duration)) {
- /*if (timer0intflag == 1) {
- LATD=0b10101010;
- while(1);
- }*/
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) freq++;
- prev_ADRESH = last_ADC_val;
- //LATD=(startTick + mod.duration)-tick;
- };
- //LATD=tresholdfreq;
- received_data |= ((freq>tresholdfreq)?1:0)<<bit_no;
- }
- return (mod.high.frequency < mod.low.frequency)? ~received_data : received_data;
- }
- unsigned char demodulatePSK(modulation mod) {
- unsigned long int startTick = 0;
- unsigned long int lastZero = 0;
- unsigned char prev_ADRESH = 0;
- unsigned char received_data = 0b00000000;
- unsigned char bit_no;
- unsigned char wave_period_count = 0;
- unsigned int tresholdfreq = 0;
- unsigned int freq=0;
- unsigned int reference_wave_offset = 0;
- unsigned int current_bit_wave_offset = 0;
- unsigned int period = 128/mod.low.frequency;
- int shift_score = 0;
- // Wait for start condition
- LATD |= 0b00001000; //LED4: waiting for start condition
- while (1 /*loop left with BREAK*/) {
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- prev_ADRESH = last_ADC_val;
- if (tick-lastZero < 2*period) {
- startTick=tick;
- LATD &= 0b11110111; //Clear LED4 (waiting for start cond.)
- break; //exit while(1) and start demodulation
- } else {
- //No start condition
- //Update lastZero
- lastZero = tick;
- }
- }
- prev_ADRESH = last_ADC_val;
- }
- LATD |= 0b00000100; //START CONDITION, CALIBRATING
- while (tick < (startTick + mod.duration)) {
- //Fuck calibration, Occam's razor, bitch!
- /*LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- reference_wave_offset += (tick-startTick - mod.duration/mod.low.frequency*wave_period_count);
- wave_period_count++;
- }
- prev_ADRESH = last_ADC_val;*/
- }
- //reference_wave_offset /= wave_period_count;
- LATD &= 0b11111011;
- timer0intflag = 0;
- for (bit_no = 0; bit_no < 8; bit_no++) {
- shift_score =0;
- while (tick < (startTick + mod.duration*(bit_no+1))) {
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- if ((tick-startTick)%period < period/4 || (tick-startTick)%period > 3*period/4) {
- shift_score--;
- } else {
- shift_score++;
- }
- }
- prev_ADRESH = last_ADC_val;
- }
- received_data |= ((shift_score>0)?1:0)<<bit_no;
- //LATD=11;
- }
- return (mod.high.frequency < mod.low.frequency)? ~received_data : received_data;
- }
- unsigned char max_QPSK_score(int ss00, int ss01, int ss10, int ss11) {
- int temp = ss00;
- if (ss01>temp) temp = ss01;
- if (ss10>temp) temp = ss10;
- if (ss11>temp) temp = ss11;
- return (ss00==temp) ? 0b00 :
- (ss01==temp) ? 0b01 :
- (ss10==temp) ? 0b10 :
- (ss11==temp) ? 0b11 :
- 0b00;
- }
- unsigned char demodulateQPSK(modulation mod) {
- unsigned long int startTick = 0;
- unsigned long int lastZero = 0;
- unsigned char prev_ADRESH = 0;
- unsigned char received_data = 0b00000000;
- unsigned char bit_no;
- unsigned char wave_period_count = 0;
- unsigned int tresholdfreq = 0;
- unsigned int freq=0;
- unsigned int reference_wave_offset = 0;
- unsigned int current_bit_wave_offset = 0;
- unsigned int period = 128/mod.low.frequency;
- int shift_score_00 = 0;
- int shift_score_01 = 0;
- int shift_score_10 = 0;
- int shift_score_11 = 0;
- unsigned char qpsk_temp = 0;
- // Wait for start condition
- LATD |= 0b00001000; //LED4: waiting for start condition
- while (1 /*loop left with BREAK*/) {
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- prev_ADRESH = last_ADC_val;
- if (tick-lastZero < 2*period) {
- startTick=tick;
- LATD &= 0b11110111; //Clear LED4 (waiting for start cond.)
- break; //exit while(1) and start demodulation
- } else {
- //No start condition
- //Update lastZero
- lastZero = tick;
- }
- }
- prev_ADRESH = last_ADC_val;
- }
- LATD |= 0b00000100; //START CONDITION, CALIBRATING
- while (tick < (startTick + mod.duration)) {
- //Fuck calibration, Occam's razor, bitch!
- /*LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- reference_wave_offset += (tick-startTick - mod.duration/mod.low.frequency*wave_period_count);
- wave_period_count++;
- }
- prev_ADRESH = last_ADC_val;*/
- }
- //reference_wave_offset /= wave_period_count;
- LATD &= 0b11111011;
- timer0intflag = 0;
- for (bit_no = 0; bit_no < 4; bit_no++) {
- shift_score_00 = shift_score_01 = shift_score_10 = shift_score_11 = 0;
- while (tick < (startTick + mod.duration*(bit_no+1))) {
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- if ((tick-startTick)%period < period/8 || (tick-startTick)%period > 7*period/8) {
- shift_score_00++;
- } else if ((tick-startTick)%period > period/8 && (tick-startTick)%period < 3*period/8){
- shift_score_01++;
- } else if ((tick-startTick)%period > 3*period/8 && (tick-startTick)%period < 5*period/8){
- shift_score_10++;
- } else if ((tick-startTick)%period > 5*period/8 && (tick-startTick)%period < 7*period/8){
- shift_score_11++;
- }
- }
- prev_ADRESH = last_ADC_val;
- }
- received_data |= (max_QPSK_score(shift_score_00, shift_score_01, shift_score_10, shift_score_11))<<bit_no*2;
- //LATD=11;
- }
- return (mod.high.frequency < mod.low.frequency)? ~received_data : received_data;
- }
- unsigned char demodulateOOK(modulation mod) {
- unsigned long int startTick = 0;
- unsigned long int lastZero = 0;
- unsigned char prev_ADRESH = 0;
- unsigned char received_data = 0b00000000;
- unsigned char bit_no;
- unsigned int tresholdfreq = 0;
- unsigned int freq=0;
- // Wait for start condition
- LATD |= 0b00001000; //LED4: waiting for start condition
- while (1 /*loop left with BREAK*/) {
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) {
- if (tick-lastZero < 2*128/mod.low.frequency) {
- startTick=tick;
- LATD &= 0b11110111; //Clear LED4 (waiting for start cond.)
- LATD |= 0b00000100; //LED3: start condition detected
- while (tick < (startTick + mod.duration)); //wait for start cond. to end
- LATD &= 0b11111011;
- break; //exit while(1) and start demodulation
- } else {
- //No start condition
- //Update lastZero
- lastZero = tick;
- }
- }
- prev_ADRESH = last_ADC_val;
- }
- timer0intflag = 0;
- for (bit_no = 0; bit_no < 8; bit_no++) {
- startTick = tick;
- freq=0;
- while (tick < (startTick + mod.duration)) {
- LATD |= 0b00000010;
- while(!(timer0intflag)); //wait for interrupt to happen
- LATD &= 0b11111101;
- timer0intflag = 0; //Reset interrupt flag
- if (last_ADC_val > 127 && prev_ADRESH <= 127) freq++;
- prev_ADRESH = last_ADC_val;
- }
- received_data |= ((freq>(mod.low.frequency*mod.duration/256))?1:0)<<bit_no;
- //LATD=11;
- }
- return (mod.high.frequency < mod.low.frequency)? ~received_data : received_data;
- }
- void receiveStringOOK(modulation mod, unsigned char *buffer) {
- int i = 0;
- unsigned char receivedByte;
- for(i=0; i<255 && receivedByte != 0x00; i++) {
- buffer[i] = receivedByte = demodulateOOK(mod);;
- }
- if (i>=255) buffer[255] = 0x00;
- return;
- }
- unsigned char oledbuffer[256];
- void main (void) {
- unsigned int C=0;
- unsigned char next;
- unsigned char config = 0;
- char helloworld[] = "Hello World!";
- int baud;
- modulation ask;
- modulation fsk;
- modulation psk;
- modulation qpsk;
- wave start;
- setup();
- Delay10KTCYx(64);
- // These are the functions you need to use to initialise the display
- oled_init();
- oled_clear();
- oled_refresh();
- ADC_Init();
- Delay10KTCYx(64);
- fsk.high.frequency = 2;
- fsk.high.amplitude = 128;
- fsk.high.phase = 0;
- fsk.low.frequency = 4;
- fsk.low.amplitude = 128;
- fsk.low.phase = 0;
- fsk.duration = 256;
- psk.high.frequency = 4;
- psk.high.amplitude = 128;
- psk.high.phase = 32;
- psk.low.frequency = 4;
- psk.low.amplitude = 128;
- psk.low.phase = 96;
- psk.duration = 128;
- ask.high.frequency = 16;
- ask.high.amplitude = 128;
- ask.high.phase = 0;
- ask.low.frequency = 16;
- ask.low.amplitude = 0;
- ask.low.phase = 0;
- ask.duration = 48;
- start.frequency=1;
- start.amplitude=128;
- start.phase=0;
- while (1) {
- oled_clear();
- receiveStringOOK(ask, oledbuffer);
- oled_puts_2x (oledbuffer);
- oled_refresh();
- while(1);
- }
- LATD=demodulateOOK(ask);
- while(1);
- //LATD=8;
- while(1) {
- //sendbyte(0b11110000, fsk);
- //LATD=(ADRESH>127)?3:0;
- LATD|=128;
- //for (baud=0; baud<4; baud++)
- // demodulate(fsk);
- LATD&= ~128;
- LATD|=64;
- for (baud=0; baud<32; baud++)
- sine(fsk.low,256);
- LATD&= ~64;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement