17
17
18
18
#include "i2c_api.h"
19
19
#include "cyhal_i2c.h"
20
+ #include "cyhal_utils.h"
21
+ #include "cyhal_hwmgr.h"
20
22
#include "mbed_error.h"
21
23
#include "mbed_assert.h"
22
24
#include "mbed_critical.h"
@@ -84,12 +86,24 @@ static void cy_i2c_event_handler(void *handler_arg, cyhal_i2c_irq_event_t event)
84
86
void i2c_init (i2c_t * obj , PinName sda , PinName scl )
85
87
{
86
88
struct i2c_s * i2c = cy_get_i2c (obj );
87
- if (CY_RSLT_SUCCESS != cyhal_i2c_init (& (i2c -> hal_i2c ), sda , scl , NULL )) {
89
+ cy_rslt_t result = cyhal_i2c_init (& (i2c -> hal_i2c ), sda , scl , NULL );
90
+ if (result == CYHAL_HWMGR_RSLT_ERR_INUSE ) {
91
+ // MBED I2C driver currently does not support free, so we will allow I2C to be reallocated.
92
+ // TODO: once the the I2C driver properly supports free, this need to be fixed so that clocks and pins are no longer leaked.
93
+ cyhal_hwmgr_free (& (i2c -> hal_i2c .resource ));
94
+ cyhal_hwmgr_set_unconfigured (i2c -> hal_i2c .resource .type , i2c -> hal_i2c .resource .block_num , i2c -> hal_i2c .resource .channel_num );
95
+ cyhal_resource_inst_t pin_rsc = cyhal_utils_get_gpio_resource (sda );
96
+ cyhal_hwmgr_free (& pin_rsc );
97
+ pin_rsc = cyhal_utils_get_gpio_resource (scl );
98
+ cyhal_hwmgr_free (& pin_rsc );
99
+ result = cyhal_i2c_init (& (i2c -> hal_i2c ), sda , scl , NULL );
100
+ }
101
+ if (CY_RSLT_SUCCESS != result ) {
88
102
MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER_I2C , MBED_ERROR_CODE_FAILED_OPERATION ), "cyhal_i2c_init" );
89
103
}
90
104
i2c -> cfg .is_slave = false;
91
105
i2c -> cfg .address = 0 ;
92
- i2c -> cfg .frequencyhal_hz = 400 ;
106
+ i2c -> cfg .frequencyhal_hz = 400000 ;
93
107
i2c -> async_handler = NULL ;
94
108
cyhal_i2c_register_irq (& (i2c -> hal_i2c ), & cy_i2c_event_handler , obj );
95
109
cyhal_i2c_irq_enable (& (i2c -> hal_i2c ), (cyhal_i2c_irq_event_t )(CYHAL_I2C_SLAVE_READ_EVENT | CYHAL_I2C_SLAVE_WRITE_EVENT | CYHAL_I2C_SLAVE_ERR_EVENT | CYHAL_I2C_SLAVE_RD_CMPLT_EVENT | CYHAL_I2C_SLAVE_WR_CMPLT_EVENT | CYHAL_I2C_MASTER_ERR_EVENT | CYHAL_I2C_MASTER_RD_CMPLT_EVENT | CYHAL_I2C_MASTER_WR_CMPLT_EVENT ), true);
@@ -112,14 +126,17 @@ int i2c_start(i2c_t *obj)
112
126
113
127
int i2c_stop (i2c_t * obj )
114
128
{
115
- // Not supported; start/stop is generated by i2c_read/i2c_write
116
- return -1 ;
129
+ struct i2c_s * i2c = cy_get_i2c (obj );
130
+ if (i2c -> hal_i2c .context .state != CY_SCB_I2C_IDLE ) {
131
+ return Cy_SCB_I2C_MasterSendStop (i2c -> hal_i2c .base , CY_I2C_DEFAULT_TIMEOUT , & (i2c -> hal_i2c .context ));
132
+ }
133
+ return 0 ;
117
134
}
118
135
119
136
int i2c_read (i2c_t * obj , int address , char * data , int length , int stop )
120
137
{
121
138
struct i2c_s * i2c = cy_get_i2c (obj );
122
- if (CY_RSLT_SUCCESS != cyhal_i2c_master_recv (& (i2c -> hal_i2c ), address >> 1 , (uint8_t * )data , (uint16_t )length , CY_I2C_DEFAULT_TIMEOUT )) {
139
+ if (CY_RSLT_SUCCESS != cyhal_i2c_master_read (& (i2c -> hal_i2c ), address >> 1 , (uint8_t * )data , (uint16_t )length , CY_I2C_DEFAULT_TIMEOUT )) {
123
140
return (int )I2C_ERROR_NO_SLAVE ;
124
141
}
125
142
return length ;
@@ -128,7 +145,7 @@ int i2c_read(i2c_t *obj, int address, char *data, int length, int stop)
128
145
int i2c_write (i2c_t * obj , int address , const char * data , int length , int stop )
129
146
{
130
147
struct i2c_s * i2c = cy_get_i2c (obj );
131
- if (CY_RSLT_SUCCESS != cyhal_i2c_master_send (& (i2c -> hal_i2c ), address >> 1 , (const uint8_t * )data , (uint16_t )length , CY_I2C_DEFAULT_TIMEOUT )) {
148
+ if (CY_RSLT_SUCCESS != cyhal_i2c_master_write (& (i2c -> hal_i2c ), address >> 1 , (const uint8_t * )data , (uint16_t )length , CY_I2C_DEFAULT_TIMEOUT )) {
132
149
return (int )I2C_ERROR_NO_SLAVE ;
133
150
}
134
151
// NOTE: HAL does not report how many bytes were actually sent in case of early NAK
@@ -153,7 +170,10 @@ int i2c_byte_read(i2c_t *obj, int last)
153
170
int i2c_byte_write (i2c_t * obj , int data )
154
171
{
155
172
struct i2c_s * i2c = cy_get_i2c (obj );
156
- cy_en_scb_i2c_status_t status = Cy_SCB_I2C_MasterWriteByte (i2c -> hal_i2c .base , (uint8_t )data , CY_I2C_DEFAULT_TIMEOUT , & (i2c -> hal_i2c .context ));
173
+ // If we have not yet written the address, the first byte being sent is the address.
174
+ cy_en_scb_i2c_status_t status = i2c -> hal_i2c .context .state == CY_SCB_I2C_IDLE
175
+ ? Cy_SCB_I2C_MasterSendStart (i2c -> hal_i2c .base , data >> 1 , CY_SCB_I2C_WRITE_XFER , CY_I2C_DEFAULT_TIMEOUT , & (i2c -> hal_i2c .context ))
176
+ : Cy_SCB_I2C_MasterWriteByte (i2c -> hal_i2c .base , (uint8_t )data , CY_I2C_DEFAULT_TIMEOUT , & (i2c -> hal_i2c .context ));
157
177
switch (status ) {
158
178
case CY_SCB_I2C_MASTER_MANUAL_TIMEOUT :
159
179
return 2 ;
@@ -203,7 +223,7 @@ int i2c_slave_receive(i2c_t *obj)
203
223
int i2c_slave_read (i2c_t * obj , char * data , int length )
204
224
{
205
225
struct i2c_s * i2c = cy_get_i2c (obj );
206
- if (CY_RSLT_SUCCESS != cyhal_i2c_slave_recv (& (i2c -> hal_i2c ), (uint8_t * )data , (uint16_t )length , CY_I2C_DEFAULT_TIMEOUT )) {
226
+ if (CY_RSLT_SUCCESS != cyhal_i2c_slave_config_read_buff (& (i2c -> hal_i2c ), (uint8_t * )data , (uint16_t )length )) {
207
227
return 0 ;
208
228
}
209
229
return 1 ;
@@ -212,7 +232,7 @@ int i2c_slave_read(i2c_t *obj, char *data, int length)
212
232
int i2c_slave_write (i2c_t * obj , const char * data , int length )
213
233
{
214
234
struct i2c_s * i2c = cy_get_i2c (obj );
215
- if (CY_RSLT_SUCCESS != cyhal_i2c_slave_send (& (i2c -> hal_i2c ), (const uint8_t * )data , (uint16_t )length , CY_I2C_DEFAULT_TIMEOUT )) {
235
+ if (CY_RSLT_SUCCESS != cyhal_i2c_slave_config_write_buff (& (i2c -> hal_i2c ), (const uint8_t * )data , (uint16_t )length )) {
216
236
return 0 ;
217
237
}
218
238
return 1 ;
@@ -239,8 +259,8 @@ void i2c_transfer_asynch(i2c_t *obj, const void *tx, size_t tx_length, void *rx,
239
259
i2c -> async_rx_size = rx_length ;
240
260
i2c -> async_handler = (void (* )(void ))handler ;
241
261
core_util_critical_section_exit ();
242
- if (CY_RSLT_SUCCESS != cyhal_i2c_transfer_async (& (i2c -> hal_i2c ), tx , tx_length , rx , rx_length , address )) {
243
- MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER_I2C , MBED_ERROR_CODE_FAILED_OPERATION ), "cyhal_i2c_transfer_async " );
262
+ if (CY_RSLT_SUCCESS != cyhal_i2c_master_transfer_async (& (i2c -> hal_i2c ), address , tx , tx_length , rx , rx_length )) {
263
+ MBED_ERROR (MBED_MAKE_ERROR (MBED_MODULE_DRIVER_I2C , MBED_ERROR_CODE_FAILED_OPERATION ), "cyhal_i2c_master_transfer_async " );
244
264
}
245
265
}
246
266
0 commit comments