alan broad
/
carbon_v5_arm_studio
arm studio build
src/commI2C.cpp@9:cc23b2049639, 2018-08-13 (annotated)
- Committer:
- alan1974
- Date:
- Mon Aug 13 15:58:00 2018 +0000
- Revision:
- 9:cc23b2049639
- Parent:
- 8:a5316708e51d
- Child:
- 17:74d60177c6b6
udpate
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
alan1974 | 0:a91cd1b08360 | 1 | #include "mbed.h" |
alan1974 | 2:0af50f386eb2 | 2 | #include "global.h" |
alan1974 | 0:a91cd1b08360 | 3 | #include "commI2C.h" |
alan1974 | 0:a91cd1b08360 | 4 | |
alan1974 | 0:a91cd1b08360 | 5 | extern uint8_t buf_xmt[BUFFER_SIZE_I2C]; //outgoing data |
alan1974 | 0:a91cd1b08360 | 6 | extern uint8_t buf_rcv[BUFFER_SIZE_I2C]; //incoming data |
alan1974 | 0:a91cd1b08360 | 7 | I2CSlave slave(PB_9, PB_8); |
alan1974 | 0:a91cd1b08360 | 8 | DigitalInOut wake(PA_0); |
alan1974 | 0:a91cd1b08360 | 9 | |
alan1974 | 0:a91cd1b08360 | 10 | extern Serial pc; |
alan1974 | 5:abfe25f0de33 | 11 | extern bool verbose; |
alan1974 | 0:a91cd1b08360 | 12 | //#define TEST |
alan1974 | 0:a91cd1b08360 | 13 | |
alan1974 | 0:a91cd1b08360 | 14 | |
alan1974 | 0:a91cd1b08360 | 15 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 16 | // i2c_proc_init |
alan1974 | 0:a91cd1b08360 | 17 | // - init i2c comm to proc |
alan1974 | 0:a91cd1b08360 | 18 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 19 | void i2c_proc_init() |
alan1974 | 0:a91cd1b08360 | 20 | { |
alan1974 | 0:a91cd1b08360 | 21 | slave.frequency(100000); // added DRT NOT NEEDED BY SLAVE????,asb, need this ???? |
alan1974 | 0:a91cd1b08360 | 22 | uint8_t slave_address = 0xA0; //PROC code uses 7bit address shifted by one so 0xA0 (xdot) => 0x50 (PROC) |
alan1974 | 0:a91cd1b08360 | 23 | slave.address(slave_address); |
alan1974 | 0:a91cd1b08360 | 24 | //set wake hi |
alan1974 | 0:a91cd1b08360 | 25 | |
alan1974 | 0:a91cd1b08360 | 26 | return; |
alan1974 | 0:a91cd1b08360 | 27 | } |
alan1974 | 0:a91cd1b08360 | 28 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 29 | // i2c_wait4wake_lo |
alan1974 | 0:a91cd1b08360 | 30 | // - wait for the wake signal from proc to go low |
alan1974 | 0:a91cd1b08360 | 31 | // NEEDS TO BE CORRECTED, THIS WAITS FOR A HI THEN A LOW !!!! |
alan1974 | 0:a91cd1b08360 | 32 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 33 | #ifdef NOT_USED |
alan1974 | 0:a91cd1b08360 | 34 | void i2c_wait4wake_lo(void){ |
alan1974 | 0:a91cd1b08360 | 35 | wake.input(); |
alan1974 | 5:abfe25f0de33 | 36 | // if(verbose)pc.printf("\n\r waiting for wake to go hi %d",wake); |
alan1974 | 0:a91cd1b08360 | 37 | bool wakeHi= false; |
alan1974 | 0:a91cd1b08360 | 38 | while(!wakeHi){ |
alan1974 | 0:a91cd1b08360 | 39 | wait_ms(10); //need this wait else loop below will block previous printout |
alan1974 | 0:a91cd1b08360 | 40 | wakeHi = wake; // state of wake signal |
alan1974 | 0:a91cd1b08360 | 41 | } |
alan1974 | 5:abfe25f0de33 | 42 | // if(verbose)pc.printf("\n\r detected wake hi"); |
alan1974 | 0:a91cd1b08360 | 43 | wait_ms(100); //need this wait else loop below will block previous printout |
alan1974 | 0:a91cd1b08360 | 44 | //wake signal hi,wait until it goes back lo => psoc is going to wait for .... |
alan1974 | 5:abfe25f0de33 | 45 | // if(verbose)pc.printf("\n\r waiting for wake to go lo %d",wake); |
alan1974 | 0:a91cd1b08360 | 46 | bool wakeLo = true; |
alan1974 | 0:a91cd1b08360 | 47 | while(wakeLo){ |
alan1974 | 0:a91cd1b08360 | 48 | wait_ms(10); //need this wait else loop below will block previous printout |
alan1974 | 0:a91cd1b08360 | 49 | wakeLo = wake; // state of wake signal |
alan1974 | 0:a91cd1b08360 | 50 | } |
alan1974 | 5:abfe25f0de33 | 51 | //if(verbose)pc.printf("\n\r detected wake lo "); |
alan1974 | 0:a91cd1b08360 | 52 | wait_ms(100); //wait for proc to get ready for i2c comm, proc leave wake in low state |
alan1974 | 0:a91cd1b08360 | 53 | |
alan1974 | 0:a91cd1b08360 | 54 | |
alan1974 | 0:a91cd1b08360 | 55 | return; |
alan1974 | 0:a91cd1b08360 | 56 | } |
alan1974 | 0:a91cd1b08360 | 57 | #endif |
alan1974 | 0:a91cd1b08360 | 58 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 59 | // i2c_pulse_wake |
alan1974 | 0:a91cd1b08360 | 60 | // - pulse the wake signal to tell proc that xdot ready for i2c xfr |
alan1974 | 0:a91cd1b08360 | 61 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 62 | void i2c_pulse_wake(void){ |
alan1974 | 0:a91cd1b08360 | 63 | wake.mode(OpenDrain); |
alan1974 | 0:a91cd1b08360 | 64 | wake.output(); |
alan1974 | 0:a91cd1b08360 | 65 | wake = 1; |
alan1974 | 0:a91cd1b08360 | 66 | wait_ms(10); //proc uses interrupts on lora_wake, so don't need to wait,just pulse it |
alan1974 | 0:a91cd1b08360 | 67 | wake = 0; // set wake lo |
alan1974 | 0:a91cd1b08360 | 68 | wait_ms(1); |
alan1974 | 0:a91cd1b08360 | 69 | wake.input(); //go back to input mode !!! wake pull hi if go back to input mode ??? |
alan1974 | 0:a91cd1b08360 | 70 | return; |
alan1974 | 0:a91cd1b08360 | 71 | } |
alan1974 | 0:a91cd1b08360 | 72 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 73 | // i2c_proc_comm |
alan1974 | 0:a91cd1b08360 | 74 | //- set WAKE low to notify proc that's OK to read/write i2c data |
alan1974 | 0:a91cd1b08360 | 75 | //- waits FOREVER or timeout for proc to write or read i2 data |
alan1974 | 0:a91cd1b08360 | 76 | // - returns point to read or write i2c bfr |
alan1974 | 0:a91cd1b08360 | 77 | //- returns true if xdot rcvd data into buf_rcv from proc |
alan1974 | 0:a91cd1b08360 | 78 | // false if xdot wrote data from buf_xmt to proc |
alan1974 | 0:a91cd1b08360 | 79 | //- before returning sets WAKE hi |
alan1974 | 0:a91cd1b08360 | 80 | //------------------------------------------------------------------------------ |
alan1974 | 0:a91cd1b08360 | 81 | // xdot i2c slave operation: |
alan1974 | 0:a91cd1b08360 | 82 | // - xdot does not work correctly as a i2c slave |
alan1974 | 0:a91cd1b08360 | 83 | // - if xdot does not respond to first incoming bytes from master (responseTime) |
alan1974 | 0:a91cd1b08360 | 84 | // within a defined period the xdot will hang the i2c bus until it is reset |
alan1974 | 8:a5316708e51d | 85 | // - the strategy here is sit in a very tight "while loop" polling continually for |
alan1974 | 0:a91cd1b08360 | 86 | // incoming i2c bytee within the respnseTime |
alan1974 | 8:a5316708e51d | 87 | // - time around the "while loop" must be < "responseTime" |
alan1974 | 8:a5316708e51d | 88 | // - "while loop" is measured at 1.25 usec |
alan1974 | 0:a91cd1b08360 | 89 | // - responseTimes upto 80 usec have been measured to be OK |
alan1974 | 0:a91cd1b08360 | 90 | //------------------------------------------------------------------------------ |
alan1974 | 0:a91cd1b08360 | 91 | // timeout: |
alan1974 | 0:a91cd1b08360 | 92 | // - safety mechanism to get xdot back to sleep mode if proc goes unresponsive |
alan1974 | 0:a91cd1b08360 | 93 | // - cpu clock dependant..what mhz is cpu? presently this will give 1.1sec timout before |
alan1974 | 0:a91cd1b08360 | 94 | // - 0x000fffff gives a 1.1 second timeout |
alan1974 | 0:a91cd1b08360 | 95 | // - after proc wakes xdot from sleep then proc must send an i2c omd within timout |
alan1974 | 0:a91cd1b08360 | 96 | // - once xdot pulses wake to notify proc that i2c ack msg is ready, proc must do i2c read within timeout |
alan1974 | 0:a91cd1b08360 | 97 | //============================================================================== |
alan1974 | 0:a91cd1b08360 | 98 | I2C_XFR_TYPE i2c_proc_comm(void) |
alan1974 | 0:a91cd1b08360 | 99 | { |
alan1974 | 5:abfe25f0de33 | 100 | |
alan1974 | 0:a91cd1b08360 | 101 | uint32_t timeout = 0x000fffff; //1.1second timeout |
alan1974 | 0:a91cd1b08360 | 102 | |
alan1974 | 0:a91cd1b08360 | 103 | while(1){ |
alan1974 | 0:a91cd1b08360 | 104 | int i = slave.receive(); |
alan1974 | 0:a91cd1b08360 | 105 | switch (i) { |
alan1974 | 8:a5316708e51d | 106 | case I2CSlave::ReadAddressed: //xdot -> proc |
alan1974 | 0:a91cd1b08360 | 107 | slave.write((char *)buf_xmt, BUFFER_SIZE_I2C); |
alan1974 | 0:a91cd1b08360 | 108 | return I2C_WRITE; |
alan1974 | 0:a91cd1b08360 | 109 | case I2CSlave::WriteAddressed: //xdot <- proc |
alan1974 | 0:a91cd1b08360 | 110 | slave.read((char *)buf_rcv, BUFFER_SIZE_I2C); |
alan1974 | 5:abfe25f0de33 | 111 | /* |
alan1974 | 0:a91cd1b08360 | 112 | if (verbose){ |
alan1974 | 0:a91cd1b08360 | 113 | pc.printf("\n\r Incoming buffer(hex): \n\r"); |
alan1974 | 0:a91cd1b08360 | 114 | int j; |
alan1974 | 0:a91cd1b08360 | 115 | for (j = 0; j < BUFFER_SIZE_I2C; j++){ |
alan1974 | 5:abfe25f0de33 | 116 | pc.printf("%x", buf_rcv[j]); |
alan1974 | 5:abfe25f0de33 | 117 | pc.printf(" "); |
alan1974 | 5:abfe25f0de33 | 118 | } |
alan1974 | 0:a91cd1b08360 | 119 | } |
alan1974 | 5:abfe25f0de33 | 120 | */ |
alan1974 | 0:a91cd1b08360 | 121 | return I2C_READ; |
alan1974 | 0:a91cd1b08360 | 122 | default: |
alan1974 | 0:a91cd1b08360 | 123 | }; //switch |
alan1974 | 0:a91cd1b08360 | 124 | |
alan1974 | 0:a91cd1b08360 | 125 | timeout--; |
alan1974 | 9:cc23b2049639 | 126 | if(timeout == 0){ |
alan1974 | 9:cc23b2049639 | 127 | pc.printf("\r\n I2C TIMEOUT"); |
alan1974 | 9:cc23b2049639 | 128 | return I2C_WRITE; //just go to sleep |
alan1974 | 9:cc23b2049639 | 129 | } |
alan1974 | 0:a91cd1b08360 | 130 | }; //while |
alan1974 | 0:a91cd1b08360 | 131 | } |