Renamed

Dependencies:   mbed

Committer:
ffxx68
Date:
Tue Mar 29 10:06:20 2022 +0000
Revision:
5:062962db7a48
Parent:
2:dff96be9617e
Receiving the file through serial port

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ffxx68 0:07819bc70660 1 #include "mbed.h"
ffxx68 0:07819bc70660 2 #include "bit_send.h"
ffxx68 0:07819bc70660 3
ffxx68 0:07819bc70660 4 DigitalOut bit_out_port(D5);
ffxx68 0:07819bc70660 5 DigitalOut led1(LED1);
ffxx68 1:9289febf4ae9 6 // Serial pc1(USBTX,USBRX); defined in main
ffxx68 0:07819bc70660 7 Ticker bit_ticker;
ffxx68 0:07819bc70660 8 Timer total_time1;
ffxx68 5:062962db7a48 9 Timer bit_time;
ffxx68 0:07819bc70660 10
ffxx68 0:07819bc70660 11 // volatile when read & write from both interrupts and main
ffxx68 0:07819bc70660 12 // static is to keep value between calls
ffxx68 1:9289febf4ae9 13 volatile uint8_t bit_sync_flags;
ffxx68 1:9289febf4ae9 14 volatile uint64_t bit_buffer; // a 64-bits buffer (position-masked)
ffxx68 1:9289febf4ae9 15 volatile uint64_t bit_read_mask; // bit read position
ffxx68 1:9289febf4ae9 16 volatile uint64_t bit_write_mask; // bit write position
ffxx68 1:9289febf4ae9 17 volatile uint64_t bit_last_mask; // position of last bit sent
ffxx68 0:07819bc70660 18
ffxx68 1:9289febf4ae9 19 volatile uint8_t bit_repeat_count = 0;
ffxx68 1:9289febf4ae9 20 volatile uint8_t bit_cycle_count = 0;
ffxx68 0:07819bc70660 21
ffxx68 0:07819bc70660 22 volatile uint32_t total_switch_cnt = 0;
ffxx68 0:07819bc70660 23
ffxx68 0:07819bc70660 24 // To be called before a new stream is sent
ffxx68 0:07819bc70660 25 void bitHandlerInit( void ) {
ffxx68 0:07819bc70660 26
ffxx68 0:07819bc70660 27 debug_printf("bitHandlerInit\r\n") ;
ffxx68 0:07819bc70660 28
ffxx68 0:07819bc70660 29 // timing ticker counters
ffxx68 0:07819bc70660 30 bit_repeat_count = 0;
ffxx68 0:07819bc70660 31 bit_cycle_count = 0;
ffxx68 0:07819bc70660 32
ffxx68 0:07819bc70660 33 bit_sync_flags = 0; // clear all (set when needed)
ffxx68 0:07819bc70660 34
ffxx68 0:07819bc70660 35 // buffer initial positions
ffxx68 0:07819bc70660 36 bit_read_mask = 1;
ffxx68 0:07819bc70660 37 bit_write_mask = 1;
ffxx68 0:07819bc70660 38 bit_buffer = 0;
ffxx68 0:07819bc70660 39
ffxx68 0:07819bc70660 40 // start with a LOW level on output
ffxx68 0:07819bc70660 41 bit_out_port = 0;
ffxx68 0:07819bc70660 42
ffxx68 0:07819bc70660 43 // debugging counters
ffxx68 0:07819bc70660 44 total_switch_cnt = 0;
ffxx68 0:07819bc70660 45
ffxx68 0:07819bc70660 46 }
ffxx68 0:07819bc70660 47
ffxx68 0:07819bc70660 48 // Called after last bit to be sent has been sent
ffxx68 0:07819bc70660 49 void bitHandlerStop ( void ) {
ffxx68 0:07819bc70660 50
ffxx68 0:07819bc70660 51 bit_sync_flags |= BIT_LAST_SENT; // signal for no more bits to send
ffxx68 0:07819bc70660 52 bit_last_mask = bit_write_mask; // for consumer, to stop here
ffxx68 0:07819bc70660 53 // NOTE - ticker will be disabled in the handler itself
ffxx68 0:07819bc70660 54 // as it has to wait for last bit to be processed, first
ffxx68 0:07819bc70660 55
ffxx68 0:07819bc70660 56 }
ffxx68 0:07819bc70660 57
ffxx68 0:07819bc70660 58 // A bit (x) is composed of BIT_TICK_x_NCYCLES of alternating HIGH and LOW levels,
ffxx68 0:07819bc70660 59 // with each level interval lasting BIT_TICK_x_REPEAT ticker repetitions.
ffxx68 0:07819bc70660 60 // Example for bit "0" -- BIT_TICK_0_NCYCLES = 8, BIT_TICK_0_REPEAT = 2:
ffxx68 0:07819bc70660 61 // ___ ___ ___ ___
ffxx68 0:07819bc70660 62 // out _| |___| |___| |___| |_
ffxx68 0:07819bc70660 63 // cycle 7 6 5 4 3 2 1 0 ...
ffxx68 0:07819bc70660 64 // repeat 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 ...
ffxx68 0:07819bc70660 65 //
ffxx68 0:07819bc70660 66 // the bit-handler bitTickHandler(), called every BIT_TICK_DELAY (Ticker object)
ffxx68 0:07819bc70660 67 // will pull a bit from the circular buffer ( bit_buffer ),
ffxx68 0:07819bc70660 68 // which is populated from writer bitWaitSend().
ffxx68 0:07819bc70660 69 // Writer takes care of synchronization of read and write buffer pointers,
ffxx68 0:07819bc70660 70 // assuming writer is FASTER than consumer handler
ffxx68 0:07819bc70660 71 void bitTickHandler ( void )
ffxx68 0:07819bc70660 72 {
ffxx68 0:07819bc70660 73
ffxx68 0:07819bc70660 74 if ( bit_cycle_count == 0 ) {
ffxx68 0:07819bc70660 75 // New bit to be pulled off the buffer - restart counters
ffxx68 0:07819bc70660 76 if ( bit_sync_flags & BIT_LAST_PROCESSING ) {
ffxx68 0:07819bc70660 77 // stop AFTER last bit has been pulled (see below)
ffxx68 0:07819bc70660 78 bit_ticker.detach ();
ffxx68 0:07819bc70660 79 led1 = 0; // ticker stopped
ffxx68 2:dff96be9617e 80 bit_out_port = 0; // stream closure
ffxx68 0:07819bc70660 81 total_time1.stop();
ffxx68 0:07819bc70660 82 } else {
ffxx68 0:07819bc70660 83 // update read position (shift left mask)
ffxx68 0:07819bc70660 84 // and reset tick and cycle counters
ffxx68 0:07819bc70660 85 if ( ( bit_read_mask = bit_read_mask<<1 ) == 0 )
ffxx68 0:07819bc70660 86 bit_read_mask = 1; // circular buffer
ffxx68 0:07819bc70660 87 if ( bit_buffer & bit_read_mask ) {
ffxx68 0:07819bc70660 88 // bit-1 from buffer
ffxx68 0:07819bc70660 89 bit_cycle_count = BIT_TICK_1_NCYCLES;
ffxx68 0:07819bc70660 90 bit_repeat_count = BIT_TICK_1_REPEAT;
ffxx68 1:9289febf4ae9 91 bit_sync_flags |= BIT_SENDING;
ffxx68 0:07819bc70660 92 } else {
ffxx68 0:07819bc70660 93 // bit-0 from buffer
ffxx68 0:07819bc70660 94 bit_cycle_count = BIT_TICK_0_NCYCLES;
ffxx68 0:07819bc70660 95 bit_repeat_count = BIT_TICK_0_REPEAT;
ffxx68 1:9289febf4ae9 96 bit_sync_flags &= ~(BIT_SENDING);
ffxx68 0:07819bc70660 97 }
ffxx68 0:07819bc70660 98 if ( ( bit_sync_flags & BIT_LAST_SENT ) &&
ffxx68 0:07819bc70660 99 ( bit_read_mask == bit_last_mask ) ) {
ffxx68 0:07819bc70660 100 // set BEFORE last bit being processed
ffxx68 0:07819bc70660 101 bit_sync_flags |= BIT_LAST_PROCESSING;
ffxx68 0:07819bc70660 102 }
ffxx68 0:07819bc70660 103 }
ffxx68 0:07819bc70660 104 }
ffxx68 0:07819bc70660 105
ffxx68 0:07819bc70660 106 if ( --bit_repeat_count == 0 ) {
ffxx68 0:07819bc70660 107 // toggle output port level
ffxx68 0:07819bc70660 108 total_switch_cnt += 1;
ffxx68 0:07819bc70660 109 bit_out_port = !bit_out_port;
ffxx68 0:07819bc70660 110 if ( total_switch_cnt & 0x10 ) led1 != led1; // show activity
ffxx68 0:07819bc70660 111 // a ticker-repeat cycle has completed
ffxx68 0:07819bc70660 112 bit_cycle_count --;
ffxx68 1:9289febf4ae9 113 if ( bit_sync_flags & BIT_SENDING ) // the bit being sent
ffxx68 0:07819bc70660 114 bit_repeat_count = BIT_TICK_1_REPEAT;
ffxx68 0:07819bc70660 115 else
ffxx68 0:07819bc70660 116 bit_repeat_count = BIT_TICK_0_REPEAT;
ffxx68 0:07819bc70660 117 }
ffxx68 0:07819bc70660 118
ffxx68 0:07819bc70660 119 }
ffxx68 0:07819bc70660 120
ffxx68 0:07819bc70660 121 // Push a bit to the buffer.
ffxx68 0:07819bc70660 122 // Waiting in an idle loop, though not 100% busy (wait),
ffxx68 0:07819bc70660 123 // as thread signals (Mbed-RTOS) are not available on the L053R8
ffxx68 0:07819bc70660 124 int bitWaitSend ( uint8_t bit_value, uint8_t invert ) {
ffxx68 0:07819bc70660 125
ffxx68 5:062962db7a48 126 bit_time.reset();
ffxx68 5:062962db7a48 127 bit_time.start();
ffxx68 0:07819bc70660 128 // Both bit_read_position and bit_write_position cycle through the buffer
ffxx68 0:07819bc70660 129 // When they are the same, put sender on hold, for consumer to complete.
ffxx68 0:07819bc70660 130 // Polling regularly, then writing a new bit to buffer
ffxx68 0:07819bc70660 131 // when pointers are different (the slower handler has moved bit_read_mask).
ffxx68 5:062962db7a48 132 // Bit handler takes about 2ms to spool a single bit:
ffxx68 0:07819bc70660 133 // ( BIT_TICK_x_CYCLE+1 ) * BIT_TICK_x_REPEAT * BIT_TICK_DELAY (us)
ffxx68 5:062962db7a48 134 // hence, as soon as writer can write new data, it has 32x2ms to write
ffxx68 0:07819bc70660 135 // new bits before filling again the buffer.
ffxx68 0:07819bc70660 136 // Polling has to be frequent enough not to let consumer pull wrong bits...
ffxx68 0:07819bc70660 137 while ( ( bit_write_mask == bit_read_mask ) && ( bit_sync_flags & BIT_FIRST_SENT ) )
ffxx68 1:9289febf4ae9 138 wait_us ( 100 );
ffxx68 0:07819bc70660 139
ffxx68 0:07819bc70660 140 // update buffer write position (shift left mask)
ffxx68 0:07819bc70660 141 if ( ( bit_write_mask = bit_write_mask<<1 ) == 0 )
ffxx68 0:07819bc70660 142 bit_write_mask = 1; // it's a circular buffer
ffxx68 0:07819bc70660 143
ffxx68 0:07819bc70660 144 // push this bit to the buffer
ffxx68 0:07819bc70660 145 if ( (bit_value & 0x01) ^ (invert & 0x01) ) // ignore positions other than 1
ffxx68 0:07819bc70660 146 bit_buffer |= (bit_write_mask); // set
ffxx68 0:07819bc70660 147 else
ffxx68 0:07819bc70660 148 bit_buffer &= ~(bit_write_mask); // clear
ffxx68 0:07819bc70660 149
ffxx68 0:07819bc70660 150 // on first bit only, start consumer too
ffxx68 0:07819bc70660 151 if ( !(bit_sync_flags & BIT_FIRST_SENT) ) {
ffxx68 0:07819bc70660 152 bit_ticker.attach_us ( &bitTickHandler, BIT_TICK_DELAY ); // start ticker
ffxx68 0:07819bc70660 153 bit_sync_flags |= BIT_FIRST_SENT; // first bit gone
ffxx68 0:07819bc70660 154 led1 = 1; // debugging purpose (ticker on)
ffxx68 0:07819bc70660 155 total_time1.reset();
ffxx68 0:07819bc70660 156 total_time1.start();
ffxx68 0:07819bc70660 157 }
ffxx68 1:9289febf4ae9 158
ffxx68 5:062962db7a48 159 return bit_time.read_us();
ffxx68 0:07819bc70660 160
ffxx68 0:07819bc70660 161 }
ffxx68 0:07819bc70660 162
ffxx68 0:07819bc70660 163 bool bitHandlerRunning( void ) {
ffxx68 0:07819bc70660 164
ffxx68 0:07819bc70660 165 return ( !(bit_sync_flags & BIT_LAST_PROCESSING) ) ;
ffxx68 0:07819bc70660 166
ffxx68 0:07819bc70660 167 }
ffxx68 0:07819bc70660 168
ffxx68 0:07819bc70660 169 ///////////////////////////////////////////////////////////////////////////////
ffxx68 0:07819bc70660 170 /* MAIN USED FOR A STANDALONE TEST BED
ffxx68 0:07819bc70660 171 int main()
ffxx68 0:07819bc70660 172 {
ffxx68 0:07819bc70660 173
ffxx68 0:07819bc70660 174 int i, ii;
ffxx68 0:07819bc70660 175 char inVal;
ffxx68 0:07819bc70660 176
ffxx68 0:07819bc70660 177 // flashing led1 on startup
ffxx68 0:07819bc70660 178 for (i=0; i<5; i+=1) {
ffxx68 0:07819bc70660 179 wait (0.1);
ffxx68 0:07819bc70660 180 led1 = !led1;
ffxx68 0:07819bc70660 181 }
ffxx68 0:07819bc70660 182 led1 = 0;
ffxx68 0:07819bc70660 183
ffxx68 0:07819bc70660 184 pc1.baud(57600);
ffxx68 0:07819bc70660 185
ffxx68 0:07819bc70660 186 // welcome message
ffxx68 0:07819bc70660 187 pc1.printf("\n\r ** MBED ** test bit send ** \n\r");
ffxx68 0:07819bc70660 188 fflush(stdout);
ffxx68 0:07819bc70660 189
ffxx68 0:07819bc70660 190 // main loop
ffxx68 0:07819bc70660 191 while(true) {
ffxx68 0:07819bc70660 192
ffxx68 0:07819bc70660 193 pc1.printf("Hit a key ... \n\r");
ffxx68 0:07819bc70660 194 fflush(stdout);
ffxx68 0:07819bc70660 195 inVal=pc1.getc(); // wait for a key press (over serial)
ffxx68 0:07819bc70660 196
ffxx68 0:07819bc70660 197 debug_printf("%.2x ", inVal);
ffxx68 0:07819bc70660 198 for ( ii = 0; ii < 8; ii++ )
ffxx68 0:07819bc70660 199 debug_printf( "%d", ((inVal & (1<<ii))!=0) );
ffxx68 0:07819bc70660 200 debug_printf("\n\r");
ffxx68 0:07819bc70660 201
ffxx68 0:07819bc70660 202 ////////////////////////////////////////////////////////////
ffxx68 0:07819bc70660 203 // before a new bit stream to be sent
ffxx68 0:07819bc70660 204 bitHandlerInit();
ffxx68 0:07819bc70660 205 // Send bit "1" a number of times (testing)
ffxx68 0:07819bc70660 206 for ( i = 0; i < 10; i++ ) {
ffxx68 0:07819bc70660 207 for ( ii = 0; ii < 8; ii++ )
ffxx68 0:07819bc70660 208 bitWaitSend( ((inVal & (1<<ii))!=0), 0 ); // try to push a bit (waiting inside, on queue full)
ffxx68 0:07819bc70660 209 }
ffxx68 0:07819bc70660 210 // stop consumer after last bit
ffxx68 0:07819bc70660 211 bitHandlerStop();
ffxx68 0:07819bc70660 212 // time for handler to complete
ffxx68 0:07819bc70660 213 while( bitHandlerRunning() )
ffxx68 0:07819bc70660 214 wait (.1);
ffxx68 0:07819bc70660 215 ////////////////////////////////////////////////////////////
ffxx68 0:07819bc70660 216
ffxx68 0:07819bc70660 217 debug_printf("total time (us): %d \n\r", total_time1.read_us() );
ffxx68 0:07819bc70660 218 debug_printf("nr. of switches: %d \n\r", total_switch_cnt );
ffxx68 0:07819bc70660 219 debug_printf("avg time per switch (us): %d \n\r",
ffxx68 0:07819bc70660 220 total_time1.read_us()/total_switch_cnt );
ffxx68 0:07819bc70660 221
ffxx68 0:07819bc70660 222 }
ffxx68 0:07819bc70660 223
ffxx68 0:07819bc70660 224 }
ffxx68 0:07819bc70660 225 */