Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //Softserial by Joern Heinrich, for ARM Cortex M3 / leflabs maple5.
- //featuring a nonblocking software serial input on ARM Cortex M3, using
- //an interrupt routine on a pin combined with one of the four general
- //hardware timers of the ARM Cortex M3
- //Conventions: 8 bit, no parity, one stop bit
- //Serial-Input buffer: sizeable
- //1 cycle = 0.01388888888 µsec @ 72 MHz
- //50 cycles = 0.695 µsec = one digital write / read
- //bit duration @ 38400 Baud = 26,06 µsec = 1920 cycles
- const unint8 SS_receivePin = 37; //pin 37 is 5V tolerant
- const int SS_bufsize = 256; //size of input bugffer in bytes
- volatile uint8 SS_INbuf[SS_bufsize]; //input buffer, beeing filled by timercontrol
- volatile int SS_INbitcnt = -1; //bit counter of incoming byte, begins with -1 = stop bit
- volatile int SS_INwritePt = 0; //writing index pointer on input buffer
- volatile int SS_INreadPt = 0; //reading index pointer on input buffer
- int SS_baud = 38400; //default Baud rate of input
- int SS_period; //duration of one bit
- HardwareTimer timerSERin(3); //ARM COrtex M3 leaflabs maple general purpose timer
- void SoftSerSetup(int b){
- SS_baud = b;
- SS_period = 1000000 / SS_baud; //Binary modulation, bit rate = baud rate, bitPeriod in µsec
- //38400 Baud : 26,042 µs
- //2400 Baud : 416,66666 µS
- pinMode(SS_receivePin, INPUT_PULLUP); //first: stop bit pulls LOW
- timerSERin.pause();
- timerSERin.setMode(2, TIMER_OUTPUT_COMPARE);
- timerSERin.setPeriod(SS_period); // in microseconds
- timerSERin.setCompare(2, timerSERin.getOverflow()-1 ); // Interrupt just before Overflow
- timerSERin.attachInterrupt(2, SS_NextBit);
- timerSERin.refresh();
- timerSERin.pause();
- attachInterrupt(SS_receivePin, SS_OnPinChange, FALLING); //SS_receivePin = 37, 5V tolerant
- }
- void SS_OnPinChange(){ //interrupt gets called, when pin goes LOW in start bit
- if (SS_INbitcnt==-1) { //start bit received, new byte underways
- SS_INbitcnt++; // Inbitcnt = 0 which annotates the first and LSB
- timerSERin.refresh(); // reset to zero
- timerSERin.resume(); // start timer.
- //for all those to which here is lacking the half-Bit-period delay for a "centering"
- // of the first bit read after the start bit, be assured:
- //The interrupt routine overhead, the Timer refresh and resume
- // is well enough to provide a "digital read" set off so far from the next input pin
- // digital level change to perform secure communication at baud rates from 600 baud
- // up to 115200 baud on the ARM Cortex M3 (leflabs maple)
- }
- }
- void SS_NextBit(){ //called by timer interrupt
- uint8 b=0;
- b = digitalRead(SS_receivePin); //HIGH = 1; LOW = 0
- switch (SS_INbitcnt){
- case 0: //gather first bit
- SS_INbuf[SS_INwritePt] = b; //resetting the Buffer contetnt to zero or one
- SS_INbitcnt++;
- break;
- case 1: //collect further bits...
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- SS_INbuf[SS_INwritePt] |= (b << SS_INbitcnt++); //setting appropriate bit
- break;
- case 8: //stop bit, reset of bit counter for next start bit
- timerSERin.refresh(); //reset to zero
- timerSERin.pause(); //and end working
- SS_INbitcnt = -1; //input pin interrupt active again
- if (SS_INwritePt>=SS_bufsize-1 ) {
- SS_INwritePt = 0; //cycling the buffer
- }
- else { SS_INwritePt++;}
- break;
- }
- }
- int SS_available(){ //yields the number of new bytes in the input buffer
- int i=0;
- if (SS_INwritePt != SS_INreadPt){
- if (SS_INwritePt > SS_INreadPt){
- i = SS_INwritePt-SS_INreadPt;
- }
- else {i = SS_INwritePt + SS_bufsize - SS_INreadPt;}
- }
- else {i=0;}
- return i;
- }
- char SS_read(){ //reads one byte from the input buffer and "deletes it"
- char b;
- if (SS_available() > 0) {
- //first read then increment reading index pointer, writing procedure does the same.
- b = SS_INbuf[SS_INreadPt];
- if (SS_INreadPt<SS_bufsize-1) {
- SS_INreadPt++;
- }
- else {
- SS_INreadPt=0;
- }
- }
- else b='#'; //no chars available but read anyway
- return b;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement