Fabio Fumi
/
send_to_sharp
Renamed
bit_send.cpp@5:062962db7a48, 2022-03-29 (annotated)
- 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?
User | Revision | Line number | New 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 | */ |