@@ -100,9 +100,75 @@ static void pbdrv_i2c_irq_3(void) {
100100 pbio_os_request_poll ();
101101}
102102
103- pbio_error_t pbdrv_i2c_placeholder_operation (pbdrv_i2c_dev_t * i2c_dev , const char * operation ) {
104- debug_pr ("I2C placeholder operation %s\n" , operation );
105- return PBIO_SUCCESS ;
103+ pbio_error_t pbdrv_i2c_placeholder_operation (
104+ pbio_os_state_t * state ,
105+ pbdrv_i2c_dev_t * i2c_dev ,
106+ uint8_t dev_addr ,
107+ const uint8_t * wdata ,
108+ size_t wlen ,
109+ uint8_t * rdata ,
110+ size_t rlen ,
111+ bool nxt_quirk ) {
112+
113+ PBIO_OS_ASYNC_BEGIN (state );
114+
115+ if (wlen && !wdata ) {
116+ return PBIO_ERROR_INVALID_ARG ;
117+ }
118+ if (rlen && !rdata ) {
119+ return PBIO_ERROR_INVALID_ARG ;
120+ }
121+ if (wlen > 0xff || rlen > 0xff ) {
122+ return PBIO_ERROR_INVALID_ARG ;
123+ }
124+
125+ if (i2c_dev -> busy ) {
126+ return PBIO_ERROR_BUSY ;
127+ }
128+
129+ // Prepare TX data
130+ if (wlen ) {
131+ memcpy (i2c_dev -> buffer , wdata , wlen );
132+ }
133+ i2c_dev -> busy = true;
134+ pbdrv_cache_prepare_before_dma (i2c_dev -> buffer , PRU_I2C_MAX_BYTES_PER_TXN );
135+
136+ // Kick off transfer
137+ pbdrv_rproc_ev3_pru1_shared_ram .i2c [i2c_dev -> pru_i2c_idx ].flags = PBDRV_RPROC_EV3_PRU1_I2C_PACK_FLAGS (
138+ dev_addr ,
139+ rlen ,
140+ wlen ,
141+ PBDRV_RPROC_EV3_PRU1_I2C_CMD_START | (nxt_quirk ? PBDRV_RPROC_EV3_PRU1_I2C_CMD_NXT_QUIRK : 0 )
142+ );
143+
144+ // Wait for transfer to finish
145+ PBIO_OS_AWAIT_WHILE (state , i2c_dev -> busy );
146+
147+ uint32_t flags = pbdrv_rproc_ev3_pru1_shared_ram .i2c [i2c_dev -> pru_i2c_idx ].flags ;
148+ debug_pr ("i2c %d done flags %08x\r\n" , i2c_dev -> pru_i2c_idx , flags );
149+ if (!(flags & PBDRV_RPROC_EV3_PRU1_I2C_STAT_DONE )) {
150+ debug_pr ("i2c %d not actually done???\r\n" , i2c_dev -> pru_i2c_idx );
151+ return PBIO_ERROR_FAILED ;
152+ }
153+ switch (flags & PBDRV_RPROC_EV3_PRU1_I2C_STAT_MASK ) {
154+ case PBDRV_RPROC_EV3_PRU1_I2C_STAT_OK :
155+ break ;
156+ case PBDRV_RPROC_EV3_PRU1_I2C_STAT_TIMEOUT :
157+ return PBIO_ERROR_TIMEDOUT ;
158+ case PBDRV_RPROC_EV3_PRU1_I2C_STAT_NAK :
159+ return PBIO_ERROR_IO ;
160+ default :
161+ debug_pr ("i2c %d unknown error occurred???\r\n" , i2c_dev -> pru_i2c_idx );
162+ return PBIO_ERROR_FAILED ;
163+ }
164+
165+ // If we got here, there's no error. Copy RX data.
166+ pbdrv_cache_prepare_after_dma (i2c_dev -> buffer , PRU_I2C_MAX_BYTES_PER_TXN );
167+ if (rlen ) {
168+ memcpy (rdata , & i2c_dev -> buffer [wlen ], rlen );
169+ }
170+
171+ PBIO_OS_ASYNC_END (PBIO_SUCCESS );
106172}
107173
108174static pbio_os_process_t ev3_i2c_init_process ;
0 commit comments