Fabio Fumi
/
send_to_sharp
Renamed
Embed:
(wiki syntax)
Show/hide line numbers
bit_send.cpp
00001 #include "mbed.h" 00002 #include "bit_send.h" 00003 00004 DigitalOut bit_out_port(D5); 00005 DigitalOut led1(LED1); 00006 // Serial pc1(USBTX,USBRX); defined in main 00007 Ticker bit_ticker; 00008 Timer total_time1; 00009 Timer bit_time; 00010 00011 // volatile when read & write from both interrupts and main 00012 // static is to keep value between calls 00013 volatile uint8_t bit_sync_flags; 00014 volatile uint64_t bit_buffer; // a 64-bits buffer (position-masked) 00015 volatile uint64_t bit_read_mask; // bit read position 00016 volatile uint64_t bit_write_mask; // bit write position 00017 volatile uint64_t bit_last_mask; // position of last bit sent 00018 00019 volatile uint8_t bit_repeat_count = 0; 00020 volatile uint8_t bit_cycle_count = 0; 00021 00022 volatile uint32_t total_switch_cnt = 0; 00023 00024 // To be called before a new stream is sent 00025 void bitHandlerInit( void ) { 00026 00027 debug_printf("bitHandlerInit\r\n") ; 00028 00029 // timing ticker counters 00030 bit_repeat_count = 0; 00031 bit_cycle_count = 0; 00032 00033 bit_sync_flags = 0; // clear all (set when needed) 00034 00035 // buffer initial positions 00036 bit_read_mask = 1; 00037 bit_write_mask = 1; 00038 bit_buffer = 0; 00039 00040 // start with a LOW level on output 00041 bit_out_port = 0; 00042 00043 // debugging counters 00044 total_switch_cnt = 0; 00045 00046 } 00047 00048 // Called after last bit to be sent has been sent 00049 void bitHandlerStop ( void ) { 00050 00051 bit_sync_flags |= BIT_LAST_SENT; // signal for no more bits to send 00052 bit_last_mask = bit_write_mask; // for consumer, to stop here 00053 // NOTE - ticker will be disabled in the handler itself 00054 // as it has to wait for last bit to be processed, first 00055 00056 } 00057 00058 // A bit (x) is composed of BIT_TICK_x_NCYCLES of alternating HIGH and LOW levels, 00059 // with each level interval lasting BIT_TICK_x_REPEAT ticker repetitions. 00060 // Example for bit "0" -- BIT_TICK_0_NCYCLES = 8, BIT_TICK_0_REPEAT = 2: 00061 // ___ ___ ___ ___ 00062 // out _| |___| |___| |___| |_ 00063 // cycle 7 6 5 4 3 2 1 0 ... 00064 // repeat 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ... 00065 // 00066 // the bit-handler bitTickHandler(), called every BIT_TICK_DELAY (Ticker object) 00067 // will pull a bit from the circular buffer ( bit_buffer ), 00068 // which is populated from writer bitWaitSend(). 00069 // Writer takes care of synchronization of read and write buffer pointers, 00070 // assuming writer is FASTER than consumer handler 00071 void bitTickHandler ( void ) 00072 { 00073 00074 if ( bit_cycle_count == 0 ) { 00075 // New bit to be pulled off the buffer - restart counters 00076 if ( bit_sync_flags & BIT_LAST_PROCESSING ) { 00077 // stop AFTER last bit has been pulled (see below) 00078 bit_ticker.detach (); 00079 led1 = 0; // ticker stopped 00080 bit_out_port = 0; // stream closure 00081 total_time1.stop(); 00082 } else { 00083 // update read position (shift left mask) 00084 // and reset tick and cycle counters 00085 if ( ( bit_read_mask = bit_read_mask<<1 ) == 0 ) 00086 bit_read_mask = 1; // circular buffer 00087 if ( bit_buffer & bit_read_mask ) { 00088 // bit-1 from buffer 00089 bit_cycle_count = BIT_TICK_1_NCYCLES; 00090 bit_repeat_count = BIT_TICK_1_REPEAT; 00091 bit_sync_flags |= BIT_SENDING; 00092 } else { 00093 // bit-0 from buffer 00094 bit_cycle_count = BIT_TICK_0_NCYCLES; 00095 bit_repeat_count = BIT_TICK_0_REPEAT; 00096 bit_sync_flags &= ~(BIT_SENDING); 00097 } 00098 if ( ( bit_sync_flags & BIT_LAST_SENT ) && 00099 ( bit_read_mask == bit_last_mask ) ) { 00100 // set BEFORE last bit being processed 00101 bit_sync_flags |= BIT_LAST_PROCESSING; 00102 } 00103 } 00104 } 00105 00106 if ( --bit_repeat_count == 0 ) { 00107 // toggle output port level 00108 total_switch_cnt += 1; 00109 bit_out_port = !bit_out_port; 00110 if ( total_switch_cnt & 0x10 ) led1 != led1; // show activity 00111 // a ticker-repeat cycle has completed 00112 bit_cycle_count --; 00113 if ( bit_sync_flags & BIT_SENDING ) // the bit being sent 00114 bit_repeat_count = BIT_TICK_1_REPEAT; 00115 else 00116 bit_repeat_count = BIT_TICK_0_REPEAT; 00117 } 00118 00119 } 00120 00121 // Push a bit to the buffer. 00122 // Waiting in an idle loop, though not 100% busy (wait), 00123 // as thread signals (Mbed-RTOS) are not available on the L053R8 00124 int bitWaitSend ( uint8_t bit_value, uint8_t invert ) { 00125 00126 bit_time.reset(); 00127 bit_time.start(); 00128 // Both bit_read_position and bit_write_position cycle through the buffer 00129 // When they are the same, put sender on hold, for consumer to complete. 00130 // Polling regularly, then writing a new bit to buffer 00131 // when pointers are different (the slower handler has moved bit_read_mask). 00132 // Bit handler takes about 2ms to spool a single bit: 00133 // ( BIT_TICK_x_CYCLE+1 ) * BIT_TICK_x_REPEAT * BIT_TICK_DELAY (us) 00134 // hence, as soon as writer can write new data, it has 32x2ms to write 00135 // new bits before filling again the buffer. 00136 // Polling has to be frequent enough not to let consumer pull wrong bits... 00137 while ( ( bit_write_mask == bit_read_mask ) && ( bit_sync_flags & BIT_FIRST_SENT ) ) 00138 wait_us ( 100 ); 00139 00140 // update buffer write position (shift left mask) 00141 if ( ( bit_write_mask = bit_write_mask<<1 ) == 0 ) 00142 bit_write_mask = 1; // it's a circular buffer 00143 00144 // push this bit to the buffer 00145 if ( (bit_value & 0x01) ^ (invert & 0x01) ) // ignore positions other than 1 00146 bit_buffer |= (bit_write_mask); // set 00147 else 00148 bit_buffer &= ~(bit_write_mask); // clear 00149 00150 // on first bit only, start consumer too 00151 if ( !(bit_sync_flags & BIT_FIRST_SENT) ) { 00152 bit_ticker.attach_us ( &bitTickHandler, BIT_TICK_DELAY ); // start ticker 00153 bit_sync_flags |= BIT_FIRST_SENT; // first bit gone 00154 led1 = 1; // debugging purpose (ticker on) 00155 total_time1.reset(); 00156 total_time1.start(); 00157 } 00158 00159 return bit_time.read_us(); 00160 00161 } 00162 00163 bool bitHandlerRunning( void ) { 00164 00165 return ( !(bit_sync_flags & BIT_LAST_PROCESSING) ) ; 00166 00167 } 00168 00169 /////////////////////////////////////////////////////////////////////////////// 00170 /* MAIN USED FOR A STANDALONE TEST BED 00171 int main() 00172 { 00173 00174 int i, ii; 00175 char inVal; 00176 00177 // flashing led1 on startup 00178 for (i=0; i<5; i+=1) { 00179 wait (0.1); 00180 led1 = !led1; 00181 } 00182 led1 = 0; 00183 00184 pc1.baud(57600); 00185 00186 // welcome message 00187 pc1.printf("\n\r ** MBED ** test bit send ** \n\r"); 00188 fflush(stdout); 00189 00190 // main loop 00191 while(true) { 00192 00193 pc1.printf("Hit a key ... \n\r"); 00194 fflush(stdout); 00195 inVal=pc1.getc(); // wait for a key press (over serial) 00196 00197 debug_printf("%.2x ", inVal); 00198 for ( ii = 0; ii < 8; ii++ ) 00199 debug_printf( "%d", ((inVal & (1<<ii))!=0) ); 00200 debug_printf("\n\r"); 00201 00202 //////////////////////////////////////////////////////////// 00203 // before a new bit stream to be sent 00204 bitHandlerInit(); 00205 // Send bit "1" a number of times (testing) 00206 for ( i = 0; i < 10; i++ ) { 00207 for ( ii = 0; ii < 8; ii++ ) 00208 bitWaitSend( ((inVal & (1<<ii))!=0), 0 ); // try to push a bit (waiting inside, on queue full) 00209 } 00210 // stop consumer after last bit 00211 bitHandlerStop(); 00212 // time for handler to complete 00213 while( bitHandlerRunning() ) 00214 wait (.1); 00215 //////////////////////////////////////////////////////////// 00216 00217 debug_printf("total time (us): %d \n\r", total_time1.read_us() ); 00218 debug_printf("nr. of switches: %d \n\r", total_switch_cnt ); 00219 debug_printf("avg time per switch (us): %d \n\r", 00220 total_time1.read_us()/total_switch_cnt ); 00221 00222 } 00223 00224 } 00225 */
Generated on Sat Jul 16 2022 05:01:30 by 1.7.2