init
This commit is contained in:
commit
bcc466f985
468
main.c
Normal file
468
main.c
Normal file
@ -0,0 +1,468 @@
|
||||
/*
|
||||
* File: main.c
|
||||
* Author: Bruno Rybársky
|
||||
*
|
||||
* Created on November 17, 2022, 12:49 PM
|
||||
*/
|
||||
|
||||
//PINS
|
||||
//GP0 - Button 1
|
||||
//GP1 - Button 2
|
||||
//GP2 - Unused
|
||||
//GP3 - Unused
|
||||
//GP4 - Serial TX
|
||||
//GP5 - Serial RX
|
||||
|
||||
//END PINS
|
||||
|
||||
|
||||
//FLAGS
|
||||
|
||||
//Flag:
|
||||
|
||||
// Flag, 0: Debounced power outage restore GPIOdeb,3
|
||||
// Flag, 1:
|
||||
// Flag, 2:
|
||||
// Flag, 3:
|
||||
// Flag, 4:
|
||||
// Flag, 5: Millis2 overflow, monitored and cleared in signal strength request
|
||||
// Flag, 6:
|
||||
// Flag, 7: GPIO0 status
|
||||
|
||||
//Flag3:
|
||||
|
||||
// Flag3, 0:
|
||||
// Flag3, 1:
|
||||
// Flag3, 2:
|
||||
// Flag3, 3: Millis3 overflow
|
||||
// Flag3, 4: SMS data beginning
|
||||
// Flag3, 5: Sending SMS data
|
||||
// Flag3, 6:
|
||||
// Flag3, 7:
|
||||
|
||||
//Flag4:
|
||||
|
||||
// Flag4, 0: SMS is 1 ON
|
||||
// Flag4, 1: SMS is 1 OFF
|
||||
// Flag4, 2: SMS is 2 ON
|
||||
// Flag4, 3: SMS is 2 OFF
|
||||
// Flag4, 4:
|
||||
// Flag4, 5:
|
||||
// Flag4, 6:
|
||||
// Flag4, 7:
|
||||
|
||||
|
||||
//START STRING RECIEVING
|
||||
//Flag2:
|
||||
|
||||
// Flag2, 0: in process of recieving "OK"
|
||||
// Flag2, 1: in process of recieving "NO CARRIER"
|
||||
// Flag2, 2: in process of recieving "ERROR"
|
||||
// Flag2, 3: in process of recieving "SMS Ready"
|
||||
// Flag2, 4:
|
||||
// Flag2, 5:
|
||||
// Flag2, 6:
|
||||
// Flag2, 7:
|
||||
|
||||
//FlagC:
|
||||
|
||||
// FlagC, 0: "OK" recieved
|
||||
// FlagC, 1: "NO CARRIER" recieved
|
||||
// FlagC, 2: "ERROR" recieved
|
||||
// FlagC, 3: "SMS Ready" recieved
|
||||
// FlagC, 4:
|
||||
// FlagC, 5:
|
||||
// FlagC, 6:
|
||||
// FlagC, 7:
|
||||
|
||||
//END STRING RECIEVING
|
||||
|
||||
//END Flags
|
||||
|
||||
|
||||
// PIC12F683 Configuration Bit Settings
|
||||
|
||||
// 'C' source line config statements
|
||||
|
||||
// CONFIG
|
||||
#pragma config FOSC = INTOSCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
|
||||
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
|
||||
#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)
|
||||
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
|
||||
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
|
||||
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
|
||||
#pragma config BOREN = ON // Brown Out Detect (BOR enabled)
|
||||
#pragma config IESO = ON // Internal External Switchover bit (Internal External Switchover mode is enabled)
|
||||
#pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)
|
||||
|
||||
#define _XTAL_FREQ 8000000 //freq for delay
|
||||
// #pragma config statements should precede project file includes.
|
||||
// Use project enums instead of #define for ON and OFF.
|
||||
|
||||
#include <xc.h>
|
||||
|
||||
/* These are the definitions */
|
||||
|
||||
const char String1[3] = "OK"; //ok response
|
||||
const char String2[11] = "NO CARRIER"; //call state change
|
||||
const char String3[6] = "ERROR"; //ok response
|
||||
const char String4[10] = "SMS Ready"; //modem startup
|
||||
|
||||
const char StringDial[14] = "+421905708125";
|
||||
|
||||
//#define TMR0_BAUD (256-133) /* trial and error value, comes to 3603 Baud */
|
||||
#define TMR0_BAUD (256-133) /* trial and error value, comes to 3603 Baud */
|
||||
|
||||
#define TxBUF_SIZE 32
|
||||
#define RxBufSize 8
|
||||
volatile char TxBuf[TxBUF_SIZE] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00};
|
||||
#define TxBUF_MASK (TxBUF_SIZE-1)
|
||||
volatile char RxBuf[RxBufSize];
|
||||
volatile char RxIPtr;
|
||||
volatile char RxIPtr_old;
|
||||
volatile char TxFlags;
|
||||
volatile char RxOPtr;
|
||||
volatile char TxIPtr;
|
||||
volatile char TxOPtr;
|
||||
volatile char TxCount;
|
||||
volatile char RxChar;
|
||||
volatile char TxChar;
|
||||
volatile char RecSkips;
|
||||
volatile char InByte;
|
||||
volatile char TxSkips = 3;
|
||||
volatile char TxCount;
|
||||
volatile char RxFlags;
|
||||
volatile char RxBufDiff;
|
||||
volatile char InChar;
|
||||
|
||||
//start parsing serial data:
|
||||
|
||||
volatile char messagePointer = 0;
|
||||
|
||||
//flags:
|
||||
volatile char Flag = 0x05;
|
||||
char Flag2 = 0xFF;
|
||||
volatile char Flag3 = 0;
|
||||
volatile char Flag4 = 0;
|
||||
char FlagC = 0;
|
||||
volatile char GPIOtemp = 0;
|
||||
volatile char GPIOdeb = 0;
|
||||
volatile char GPIOold = 0;
|
||||
|
||||
//end parsing serial data:
|
||||
|
||||
//measuring time
|
||||
volatile char Millis = 0;
|
||||
|
||||
|
||||
|
||||
/* Here's the enqueuing routine for sending data */
|
||||
|
||||
/* Enqueue data in the transmit buffer to send down the serial line */
|
||||
/* This routine adds one character at a time to the 32 byte buffer */
|
||||
/* (the size is constrained b the compiler and RAM limitations of the */
|
||||
/* processor). When a character has been added, the "new data" flag is */
|
||||
/* set to tell the interrupt routine to restart sending data. */
|
||||
/* Note: data can be added to the buffer faster than the interrupt */
|
||||
/* routine can transmit it */
|
||||
|
||||
void SendChar(char c) {
|
||||
GIE = 0; /* disable interrupts to avoid a race condition */
|
||||
TxBuf[TxOPtr++] = c;
|
||||
TxOPtr = TxOPtr & TxBUF_MASK;
|
||||
TxFlags |= 0x80;
|
||||
GIE = 1; /* safe to restart them now */
|
||||
}
|
||||
|
||||
void SendString(const char *c) {
|
||||
while (*c != 0x00) {
|
||||
SendChar(*c);
|
||||
++c;
|
||||
}
|
||||
}
|
||||
|
||||
/* here's the interrupt handler that performs the serial I-O */
|
||||
/* With an 8MHz (internal R-C) clock and the timer0 count value */
|
||||
/* defined above, this gives 2400 Baud duplex communication */
|
||||
/* As you will see from the original, it samples the incoming */
|
||||
/* data 3 times per bit */
|
||||
|
||||
/* general purpose interrupt handler */
|
||||
|
||||
|
||||
void __interrupt()isr(void) {
|
||||
if (T0IF) {
|
||||
T0IF = 0;
|
||||
TMR0 = TMR0_BAUD;
|
||||
|
||||
// Increment Millis
|
||||
//Millis++;
|
||||
//if (STATUS & (1 << 2)) { // if millis overflows
|
||||
if (!++Millis) {
|
||||
// if millis overflows
|
||||
// Debouncing code sampling GPIO2 only runs when Millis overflows
|
||||
//if ((GPIOtemp & 0x0D) != (GPIO & 0x0D)) { // compare current input with last round
|
||||
|
||||
if ((GPIO & 0x03) != GPIOold){
|
||||
GPIOtemp = (GPIO & 0x03) ^ GPIOold;
|
||||
GPIOold = GPIO & 0x03;
|
||||
// GPIO2 changed, perform debouncing
|
||||
if (GPIOtemp & 0x01) {
|
||||
if (!(GPIO & 0x01)) {
|
||||
GPIOdeb |= (1 << 4); // arm
|
||||
}
|
||||
else {
|
||||
GPIOdeb |= (1 << 5); // disarm
|
||||
}
|
||||
}
|
||||
|
||||
if (GPIOtemp & 0x02) {
|
||||
if (!(GPIO & 0x02)) {
|
||||
GPIOdeb |= (1 << 6); // arm
|
||||
}
|
||||
else {
|
||||
GPIOdeb |= (1 << 7); // disarm
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Routine to receive asynchronous data from GPIO5
|
||||
// credit: http://www.electro-tech-online.com/micro-controllers/18828-finding-serial-start-bit-bit-banging.html#post117227
|
||||
asm("decfsz _RecSkips,F");
|
||||
asm("goto DoneRS232_Rx");
|
||||
asm("btfss _RxFlags,0"); // b_receiving
|
||||
asm("goto get_start_bit");
|
||||
asm("bsf STATUS, 0");
|
||||
asm("btfss GPIO, 5");
|
||||
asm("bcf STATUS,0");
|
||||
asm("rrf _InByte,F");
|
||||
asm("movlw 3");
|
||||
asm("movwf _RecSkips");
|
||||
asm("btfss STATUS, 0");
|
||||
asm("goto DoneRS232_Rx");
|
||||
asm("movf _InByte,W");
|
||||
asm("movwf _RxChar");
|
||||
asm("bsf _RxFlags,1"); // b_byte_available
|
||||
asm("bcf _RxFlags,0"); // b_receiving
|
||||
RxBuf[RxIPtr++] = RxChar; /* write received byte to circular buffer */
|
||||
RxIPtr = RxIPtr & 0x7;
|
||||
asm("goto DoneRS232_Rx");
|
||||
|
||||
asm("get_start_bit:");
|
||||
|
||||
asm("incf _RecSkips,F"); // set to 1
|
||||
asm("btfsc GPIO, 5");
|
||||
asm("goto DoneRS232_Rx");
|
||||
asm("movlw 4");
|
||||
asm("movwf _RecSkips");
|
||||
asm("bsf _RxFlags,0"); // b_receiving
|
||||
asm("movlw 80h");
|
||||
asm("movwf _InByte");
|
||||
asm("DoneRS232_Rx:");
|
||||
|
||||
// Code to transmit data from GPIO.4
|
||||
// Note: this can be done while reception is in progress,
|
||||
// it's full duplex
|
||||
// Here check if there is data being sent, or ready to send
|
||||
asm("btfsc _TxFlags, 6"); /* already sending ?*/
|
||||
asm("goto Tx_Sending");
|
||||
asm("btfsc _TxFlags, 7"); // data to send
|
||||
asm("goto Tx_Start_Bit");
|
||||
asm("incf _TxSkips, F"); // set back to 1, so we retest next time round
|
||||
asm("goto DoneRS232_Tx"); // nothing to do
|
||||
|
||||
// come here to start sending a new byte
|
||||
asm("Tx_Start_Bit:");
|
||||
asm("decfsz _TxSkips, f");
|
||||
asm("goto DoneRS232_Tx");
|
||||
asm("bcf GPIO, 4"); // hardware start bit
|
||||
|
||||
TxChar = TxBuf[TxIPtr++];
|
||||
TxIPtr = TxIPtr & TxBUF_MASK;
|
||||
|
||||
TxFlags = 8; // initialise bit count, clear FULL flag
|
||||
asm("bsf _TxFlags, 6"); // indicate we are sending data
|
||||
TxSkips = 3;
|
||||
asm("goto DoneRS232_Tx");
|
||||
|
||||
//here if we are already in the process of sending data
|
||||
asm("Tx_Sending:");
|
||||
asm("decfsz _TxSkips, F"); // only waggle o/p every third intr.
|
||||
asm("goto DoneRS232_Tx");
|
||||
|
||||
asm("btfsc _TxFlags, 5"); // time to send stop bit?
|
||||
asm("goto Tx_Stop_Bit");
|
||||
|
||||
asm("bcf STATUS, 0"); // carry bit
|
||||
asm("rrf _TxChar, f");
|
||||
asm("btfss STATUS, 0");
|
||||
asm("goto Tx_Set_Bit");
|
||||
asm("bsf GPIO, 4");
|
||||
asm("goto Tx_Sent_Bit");
|
||||
asm("Tx_Set_Bit:");
|
||||
asm("bcf GPIO, 4");
|
||||
// here we have sent the data bit, decrement the bit counter
|
||||
asm("Tx_Sent_Bit:");
|
||||
asm("movlw 3");
|
||||
asm("movwf _TxSkips"); // reset Tx skip counter for 3 more intrs
|
||||
asm("decf _TxFlags, F"); // bit count in lower 3 bits
|
||||
asm("movf _TxFlags, W");
|
||||
asm("andlw 7");
|
||||
asm("btfss STATUS, 2"); // if result is zero
|
||||
asm("goto DoneRS232_Tx");
|
||||
asm("bsf _TxFlags, 5"); // all data sent, sent stop bit next time
|
||||
asm("goto DoneRS232_Tx");
|
||||
|
||||
// here to send the stop bit and check if there''s more data
|
||||
// to send, once this byte has completed
|
||||
asm("Tx_Stop_Bit:");
|
||||
asm("bsf GPIO, 4");
|
||||
asm("movlw 3");
|
||||
asm("movwf _TxSkips");
|
||||
asm("bcf _TxFlags, 6"); // sending_data flag
|
||||
asm("bcf _TxFlags, 5"); // send_stop_bit flag
|
||||
TxCount = 1 + TxOPtr - TxIPtr;
|
||||
asm("decfsz _TxCount, F"); // counter of number of chars still to send
|
||||
asm("goto Tx_More");
|
||||
asm("goto DoneRS232_Tx"); // all sent
|
||||
|
||||
asm("Tx_More:");
|
||||
asm("bsf _TxFlags, 7"); // signify more data to send
|
||||
|
||||
asm("DoneRS232_Tx:");
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void init(void) {
|
||||
OPTION_REGbits.T0CS = 0;
|
||||
OPTION_REGbits.PSA = 0;
|
||||
OPTION_REGbits.PS0 = 0;
|
||||
OPTION_REGbits.PS1 = 0;
|
||||
OPTION_REGbits.PS2 = 0;
|
||||
OPTION_REGbits.nGPPU = 0;
|
||||
INTCONbits.T0IE = 1;
|
||||
INTCONbits.GIE = 1;
|
||||
CMCON0bits.CM0 = 1;
|
||||
CMCON0bits.CM1 = 1;
|
||||
CMCON0bits.CM2 = 1;
|
||||
OSCCONbits.IRCF0 = 1;
|
||||
OSCCONbits.IRCF1 = 1;
|
||||
OSCCONbits.IRCF2 = 1;
|
||||
TRISIObits.TRISIO5 = 1;
|
||||
TRISIObits.TRISIO4 = 0;
|
||||
TRISIObits.TRISIO1 = 1;
|
||||
TRISIObits.TRISIO0 = 1;
|
||||
WPUbits.WPU1 = 1;
|
||||
WPUbits.WPU0 = 1;
|
||||
ADCON0bits.ADON = 0;
|
||||
ANSELbits.ANS0 = 0;
|
||||
ANSELbits.ANS1 = 0;
|
||||
ANSELbits.ANS2 = 0;
|
||||
ANSELbits.ANS3 = 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
int startSMS() {
|
||||
if (FlagC & (1 << 3)) {
|
||||
SendString("AT+CMGS=\"");
|
||||
SendString(StringDial);
|
||||
SendString("\"\n");
|
||||
Flag3 |= (1 << 5);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void processString(const char *string, volatile char *inputCharacter, const int flagBit) {
|
||||
if (Flag2 & (1 << flagBit)) {
|
||||
if (!string[messagePointer]) {
|
||||
FlagC |= (1 << flagBit);
|
||||
Flag2 &= ~(1 << flagBit);
|
||||
if (flagBit == 3) {
|
||||
SendString("AT+CMGF=1\r\n");
|
||||
}
|
||||
}
|
||||
if (*inputCharacter != string[messagePointer]) {
|
||||
Flag2 &= ~(1 << flagBit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handleGPIO(const int pin, const int flagBit) {
|
||||
if (GPIOdeb & (1 << pin)) {
|
||||
GPIOdeb &= ~(1 << pin);
|
||||
if(startSMS()){
|
||||
Flag4 |= (1 << flagBit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
init();
|
||||
SendChar('\n');
|
||||
while (1) {
|
||||
|
||||
handleGPIO(6, 0);
|
||||
handleGPIO(7, 1);
|
||||
handleGPIO(4, 2);
|
||||
handleGPIO(5, 3);
|
||||
|
||||
if (RxIPtr != RxIPtr_old) {
|
||||
if (RxIPtr < RxIPtr_old) {
|
||||
RxBufDiff = RxBufSize - (RxIPtr_old - RxIPtr);
|
||||
} else {
|
||||
RxBufDiff = RxIPtr - RxIPtr_old;
|
||||
}
|
||||
for (char iy = 0; iy < RxBufDiff; iy++) {
|
||||
InChar = RxBuf[iy + RxIPtr_old];
|
||||
if (InChar == 0x0A) {
|
||||
Flag2 = 0xFF;
|
||||
messagePointer = 0;
|
||||
} else {
|
||||
if (InChar == '>') {
|
||||
if (Flag3 & (1 << 5)) {
|
||||
|
||||
if (Flag4 & (1 << 0)) {
|
||||
SendString("1 ON");
|
||||
Flag4 &= ~(1 << 0);
|
||||
}
|
||||
|
||||
if (Flag4 & (1 << 1)) {
|
||||
SendString("1 OFF");
|
||||
Flag4 &= ~(1 << 1);
|
||||
}
|
||||
|
||||
if (Flag4 & (1 << 2)) {
|
||||
SendString("2 ON");
|
||||
Flag4 &= ~(1 << 2);
|
||||
}
|
||||
|
||||
if (Flag4 & (1 << 3)) {
|
||||
SendString("2 OFF");
|
||||
Flag4 &= ~(1 << 3);
|
||||
}
|
||||
|
||||
SendChar(26);
|
||||
Flag3 &= ~(1 << 5);
|
||||
}
|
||||
}
|
||||
|
||||
processString(String1, &InChar, 0);
|
||||
processString(String2, &InChar, 1);
|
||||
processString(String3, &InChar, 2);
|
||||
processString(String4, &InChar, 3);
|
||||
|
||||
messagePointer++;
|
||||
}
|
||||
}
|
||||
RxIPtr_old = RxIPtr;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user