BlinkenArea - GitList
Repositories
Blog
Wiki
bluebox
Code
Commits
Branches
Tags
Search
Tree:
fd252ce
Branches
Tags
master
bluebox
BlueDataDistributor
firmware
serial.c
initial commit of files from bluebox project
Stefan Schuermans
commited
fd252ce
at 2015-12-19 20:16:38
serial.c
Blame
History
Raw
/* BlueDataDistributor - data distribution module from ethernet to 32 serial ports * version 0.1.1 date 2006-10-07 * Copyright (C) 2006 Stefan Schuermans <stefan@blinkenarea.org> * a BlinkenArea project - http://www.blinkenarea.org/ */ #include <string.h> #include <avr/io.h> #include "serial.h" #include "status.h" // ring buffer for serial data to output on the serial ports // - every element contains SERIAL_OUTPUT_CNT bytes #define SERIAL_BUFFER_CNT 32 unsigned char SerialBuffers[SERIAL_BUFFER_CNT][SERIAL_OUTPUT_CNT]; // pointers for above ring buffer volatile unsigned char SerialBufferStart = 0; volatile unsigned char SerialBufferEnd = 0; // bit mask of next bit to output (0x00 for start bit, 0xFF for stop bit) volatile unsigned char SerialBitMask = 0x00; // initialize void SerialInit( void ) // (extern) { //set up IO pins of serial outputs as output PORTB |= 0xFD; // PB1 is used for programming DDRB |= 0xFD; PORTD = 0xFF; DDRD = 0xFF; PORTE |= 0xEC; // PE0-1 are used for programming, PE4 is interrupt input DDRE |= 0xEC; PORTF = 0xFF; DDRF = 0xFF; PORTG |= 0x17; // PG3 is status LED, PG5-7 do not exist DDRG |= 0x17; } // output the specified bit of a byte on every serial port // - data must point to SERIAL_OUTPUT_CNT=32 bytes // - bit_mask must be 0x01, 0x02, ... 0x80 for bits 0, 1, ..., 7 // - bit_mask must be 0x00 for the start bit and 0xFF for the stop bit // extern void SerialOutputBit( unsigned char * data, unsigned char bit_mask ); // this function is written in assembler, see serial_asm.S // bit time of serial port elapsed void SerialOutputBitTime( void ) { unsigned char start; // no data to output if( SerialBufferStart == SerialBufferEnd ) return; // output current bit SerialOutputBit( SerialBuffers[SerialBufferStart], SerialBitMask ); // next bit switch( SerialBitMask ) { case 0x00: // start bit -> first bit SerialBitMask = 0x01; break; case 0x80: // last bit -> stop bit SerialBitMask = 0xFF; break; case 0xFF: // stop bit -> next byte SerialBitMask = 0x00; start = SerialBufferStart + 1; if( start >= SERIAL_BUFFER_CNT ) start = 0; SerialBufferStart = start; break; default: // next bit SerialBitMask <<= 1; break; } } // schedule data to be output on serial ports // - data_len should be a multiple of SERIAL_OUTPUT_CNT void SerialOutput( unsigned char * data, unsigned int data_len ) { unsigned char cnt, end, i, new_end; // get number of bytes to output on each serial port cnt = data_len / SERIAL_OUTPUT_CNT; if( cnt > 0 ) StatusEventSerial( ); // put entrie data set into buffers - or nothing of data set end = SerialBufferEnd; for( i = 0; i < cnt; i++ ) { // check if all buffers are full new_end = end + 1; if( new_end >= SERIAL_BUFFER_CNT ) new_end = 0; if( new_end == SerialBufferStart ) return; // all buffers are full -> drop all bytes from this data set (do not use only the first bytes of the data set, there's nothing we can do about too much data coming in on ethernet) // copy data into next buffer memcpy( SerialBuffers[end], data, SERIAL_OUTPUT_CNT ); // mark buffer temporary as filled end = new_end; // next byte (for each serial port) data += SERIAL_OUTPUT_CNT; } // mark buffers as filled // - do this after it is certain that entire data set could be put into buffers SerialBufferEnd = end; }