#include <inttypes.h> #include <stdbool.h> #include <avr/io.h> #include "SDI12.h" // 0.1 header file for this library #define _BUFFER_SIZE 64 // 0.2 max RX buffer size #define DISABLED 0 // 0.3 value for DISABLED state #define ENABLED 1 // 0.4 value for ENABLED state #define HOLDING 2 // 0.5 value for DISABLED state #define TRANSMITTING 3 // 0.6 value for TRANSMITTING state #define LISTENING 4 // 0.7 value for LISTENING state #define SPACING 830 // 0.8 bit timing in microseconds #define PHIGH PORTB7; #define PLOW PORTB7; #define INMODE PORTB7; #define OUTMODE PORTB7; //SDI12 *SDI12__activeObject = NULL; // 0.9 pointer to active SDI12 object uint8_t _dataPin; // 0.10 reference to the data pin bool _bufferOverflow; // 0.11 buffer overflow status // See section 0 above. // 1.1 - max buffer size char _rxBuffer[_BUFFER_SIZE]; // 1.2 - buff for incoming uint8_t _rxBufferHead = 0; // 1.3 - index of buff head uint8_t _rxBufferTail = 0; // 1.4 - index of buff tail // 2.1 - sets the state of the SDI-12 object. void SDI12_setState(uint8_t state){ if(state == HOLDING){ pinMode(_dataPin,OUTPUT); digitalWrite(_dataPin,LOW); *digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin)); return; } if(state == TRANSMITTING){ pinMode(_dataPin,OUTPUT); noInterrupts(); // supplied by Arduino.h, same as cli() return; } if(state == LISTENING) { digitalWrite(_dataPin,LOW); pinMode(_dataPin,INPUT); interrupts(); // supplied by Arduino.h, same as sei() *digitalPinToPCICR(_dataPin) |= (1<<digitalPinToPCICRbit(_dataPin)); *digitalPinToPCMSK(_dataPin) |= (1<<digitalPinToPCMSKbit(_dataPin)); } else { // implies state==DISABLED digitalWrite(_dataPin,LOW); pinMode(_dataPin,INPUT); *digitalPinToPCMSK(_dataPin) &= ~(1<<digitalPinToPCMSKbit(_dataPin)); if(!*digitalPinToPCMSK(_dataPin)){ *digitalPinToPCICR(_dataPin) &= ~(1<<digitalPinToPCICRbit(_dataPin)); } } } // 2.2 - forces a HOLDING state. void SDI12_forceHold(){ setState(HOLDING); } // 3.1 Constructor SDI12_SDI12(uint8_t dataPin){ _bufferOverflow = false; _dataPin = dataPin; } // 3.2 Destrutor SDI12_dest(){ setState(DISABLED); } // 3.3 Begin void SDI12_begin() { setState(HOLDING); setActive(); } // 3.4 End void SDI12_end() { setState(DISABLED); } // 4.1 - this function wakes up the entire sensor bus void SDI12_wakeSensors(){ SDI12_setState(TRANSMITTING); SDI12_digitalWrite(_dataPin, HIGH); delayMicroseconds(12100); digitalWrite(_dataPin, LOW); delayMicroseconds(8400); } // 4.2 - this function writes a character out on the data line void SDI12_writeChar(uint8_t out) { out |= (parity_even_bit(out)<<7); // 4.2.1 - parity bit digitalWrite(_dataPin, HIGH); // 4.2.2 - start bit delayMicroseconds(SPACING); for (byte mask = 0x01; mask; mask<<=1){ // 4.2.3 - send payload if(out & mask){ digitalWrite(_dataPin, LOW); } else{ digitalWrite(_dataPin, HIGH); } delayMicroseconds(SPACING); } digitalWrite(_dataPin, LOW); // 4.2.4 - stop bit delayMicroseconds(SPACING); } // 4.3 - this function sends out the characters of the String cmd, one by one void SDI12_sendCommand(String cmd){ wakeSensors(); // wake up sensors for (int i = 0; i < cmd.length(); i++){ writeChar(cmd[i]); // write each characters } setState(LISTENING); // listen for reply } /* ============= 5. Reading from the SDI-12 object. ===================*/ // 5.1 - reveals the number of characters available in the buffer int SDI12_available() { if(_bufferOverflow) return -1; return (_rxBufferTail + _BUFFER_SIZE - _rxBufferHead) % _BUFFER_SIZE; } // 5.2 - reveals the next character in the buffer without consuming int SDI12_peek() { if (_rxBufferHead == _rxBufferTail) return -1; // Empty buffer? If yes, -1 return _rxBuffer[_rxBufferHead]; // Otherwise, read from "head" } // 5.3 - a public function that clears the buffer contents and // resets the status of the buffer overflow. void SDI12_flush() { _rxBufferHead = _rxBufferTail = 0; _bufferOverflow = false; } // 5.4 - reads in the next character from the buffer (and moves the index ahead) int SDI12_read() { _bufferOverflow = false; //reading makes room in the buffer if (_rxBufferHead == _rxBufferTail) return -1; // Empty buffer? If yes, -1 uint8_t nextChar = _rxBuffer[_rxBufferHead]; // Otherwise, grab char at head _rxBufferHead = (_rxBufferHead + 1) % _BUFFER_SIZE; // increment head return nextChar; // return the char } // 6.1 - a method for setting the current object as the active object bool SDI12_setActive() { if (_activeObject != this) { setState(HOLDING); _activeObject = this; return true; } return false; } // 6.2 - a method for checking if this object is the active object bool SDI12_isActive() { return this == _activeObject; } // 6.1 - Passes off responsibility for the interrupt to the active object. inline void SDI12_handleInterrupt(){ if (_activeObject) _activeObject->receiveChar(); } // 6.2 - Quickly reads a new character into the buffer. void SDI12_receiveChar() { if (digitalRead(_dataPin)) // 6.2.1 - Start bit? { uint8_t newChar = 0; // 6.2.2 - Make room for char. delayMicroseconds(SPACING/2); // 6.2.3 - Wait 1/2 SPACING for (uint8_t i=0x1; i<0x80; i <<= 1) // 6.2.4 - read the 7 data bits { delayMicroseconds(SPACING); uint8_t noti = ~i; if (!digitalRead(_dataPin)) newChar |= i; else newChar &= noti; } delayMicroseconds(SPACING); // 6.2.5 - Skip the parity bit. delayMicroseconds(SPACING); // 6.2.6 - Skip the stop bit. // 6.2.7 - Overflow? If not, proceed. if ((_rxBufferTail + 1) % _BUFFER_SIZE == _rxBufferHead) { _bufferOverflow = true; } else { // 6.2.8 - Save char, advance tail. _rxBuffer[_rxBufferTail] = newChar; _rxBufferTail = (_rxBufferTail + 1) % _BUFFER_SIZE; } } } //6.3 #if defined(PCINT0_vect) ISR(PCINT0_vect){ SDI12_handleInterrupt(); } #endif #if defined(PCINT1_vect) ISR(PCINT1_vect){ SDI12_handleInterrupt(); } #endif #if defined(PCINT2_vect) ISR(PCINT2_vect){ SDI12_handleInterrupt(); } #endif #if defined(PCINT3_vect) ISR(PCINT3_vect){ SDI12_handleInterrupt(); } #endif
1. What is a Stub function? Ans : A function without any definition which presents no error when called. 2. Why there are two ld scripts generated by STM32Cube IDE? Ans: The CubeIDE always presents two different LDscripts on for generating the executable for Debugging which goes to RAM another for normal code upload that goes to flash memory. 3. What is Supervisory Mode/ privileged mode ? Ans : When you are using a Kernel then there are two modes user mode and privileged mode. In User mode the applications cant have system calls. 4. What is "make -j6" ? Ans : Make has an argument for number of jobs, so when you add -j6 it will create 6 different compiler instances, so that the systems could use multicore to the fullest. Linux people generally do add "-j $(nproc)" where nproc is a command line which returns number of processors attached. 5. What is weak attribute ? Ans : Weak attribute used to denote weak symbols which helps linkers to choose one function out of mul...
Comments
Post a Comment