Renamed

Dependencies:   mbed

Committer:
ffxx68
Date:
Fri Feb 18 11:07:34 2022 +0000
Revision:
1:9289febf4ae9
Parent:
0:07819bc70660
Child:
2:dff96be9617e
Changed repo name

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