Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Nodemcu Firmware
Commits
381726f1
Commit
381726f1
authored
Jan 16, 2017
by
devsaurus
Browse files
add i2c module
parent
4fcb1404
Changes
9
Hide whitespace changes
Inline
Side-by-side
components/driver_i2c/component.mk
0 → 100644
View file @
381726f1
COMPONENT_ADD_INCLUDEDIRS
:=
include
components/driver_i2c/i2c_sw_master.c
0 → 100644
View file @
381726f1
/******************************************************************************
* Copyright 2013-2014 Espressif Systems (Wuxi)
*
* FileName: i2c_sw_master.c
*
* Description: i2c master API
*
* Modification history:
* 2014/3/12, v1.0 create this file.
*******************************************************************************/
#include "driver/gpio.h"
#include "driver/i2c_sw_master.h"
static
uint8_t
m_nLastSDA
;
static
uint8_t
m_nLastSCL
;
static
uint8_t
pinSDA
;
static
uint8_t
pinSCL
;
/******************************************************************************
* FunctionName : i2c_sw_master_setDC
* Description : Internal used function -
* set i2c SDA and SCL bit value for half clk cycle
* Parameters : uint8_t SDA
* uint8_t SCL
* Returns : NONE
*******************************************************************************/
static
void
i2c_sw_master_setDC
(
uint8_t
SDA
,
uint8_t
SCL
)
{
uint8_t
sclLevel
;
SDA
&=
0x01
;
SCL
&=
0x01
;
m_nLastSDA
=
SDA
;
m_nLastSCL
=
SCL
;
gpio_set_level
(
pinSDA
,
SDA
);
gpio_set_level
(
pinSCL
,
SCL
);
if
(
1
==
SCL
)
{
do
{
sclLevel
=
gpio_get_level
(
pinSCL
);
}
while
(
sclLevel
==
0
);
}
}
/******************************************************************************
* FunctionName : i2c_sw_master_getDC
* Description : Internal used function -
* get i2c SDA bit value
* Parameters : NONE
* Returns : uint8_t - SDA bit value
*******************************************************************************/
static
uint8_t
i2c_sw_master_getDC
(
void
)
{
return
gpio_get_level
(
pinSDA
);
}
/******************************************************************************
* FunctionName : i2c_sw_master_init
* Description : initilize I2C bus to enable i2c operations
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_init
(
void
)
{
uint8_t
i
;
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
// when SCL = 0, toggle SDA to clear up
i2c_sw_master_setDC
(
0
,
0
);
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
// set data_cnt to max value
for
(
i
=
0
;
i
<
28
;
i
++
)
{
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 0
i2c_sw_master_setDC
(
1
,
1
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 1
}
// reset all
i2c_sw_master_stop
();
return
;
}
uint8_t
i2c_sw_master_get_pinSDA
()
{
return
pinSDA
;
}
uint8_t
i2c_sw_master_get_pinSCL
()
{
return
pinSCL
;
}
/******************************************************************************
* FunctionName : i2c_sw_master_gpio_init
* Description : config SDA and SCL gpio to open-drain output mode,
* mux and gpio num defined in i2c_sw_master.h
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_gpio_init
(
uint8
sda
,
uint8
scl
)
{
pinSDA
=
sda
;
pinSCL
=
scl
;
gpio_config_t
cfg
;
cfg
.
pin_bit_mask
=
1
<<
sda
|
1
<<
scl
;
cfg
.
mode
=
GPIO_MODE_INPUT_OUTPUT_OD
;
cfg
.
pull_up_en
=
GPIO_PULLUP_ENABLE
;
cfg
.
pull_down_en
=
GPIO_PULLDOWN_DISABLE
;
cfg
.
intr_type
=
GPIO_INTR_DISABLE
;
if
(
ESP_OK
!=
gpio_config
(
&
cfg
))
return
;
gpio_set_level
(
scl
,
1
);
gpio_set_level
(
sda
,
1
);
i2c_sw_master_init
();
}
/******************************************************************************
* FunctionName : i2c_sw_master_start
* Description : set i2c to send state
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_start
(
void
)
{
i2c_sw_master_setDC
(
1
,
m_nLastSCL
);
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
1
,
1
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 1
i2c_sw_master_setDC
(
0
,
1
);
i2c_sw_master_wait
(
5
);
// sda 0, scl 1
}
/******************************************************************************
* FunctionName : i2c_sw_master_stop
* Description : set i2c to stop sending state
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_stop
(
void
)
{
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
0
,
m_nLastSCL
);
i2c_sw_master_wait
(
5
);
// sda 0
i2c_sw_master_setDC
(
0
,
1
);
i2c_sw_master_wait
(
5
);
// sda 0, scl 1
i2c_sw_master_setDC
(
1
,
1
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 1
}
/******************************************************************************
* FunctionName : i2c_sw_master_setAck
* Description : set ack to i2c bus as level value
* Parameters : uint8_t level - 0 or 1
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_setAck
(
uint8_t
level
)
{
i2c_sw_master_setDC
(
m_nLastSDA
,
0
);
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
level
,
0
);
i2c_sw_master_wait
(
5
);
// sda level, scl 0
i2c_sw_master_setDC
(
level
,
1
);
i2c_sw_master_wait
(
8
);
// sda level, scl 1
i2c_sw_master_setDC
(
level
,
0
);
i2c_sw_master_wait
(
5
);
// sda level, scl 0
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
}
/******************************************************************************
* FunctionName : i2c_sw_master_getAck
* Description : confirm if peer send ack
* Parameters : NONE
* Returns : uint8_t - ack value, 0 or 1
*******************************************************************************/
uint8_t
i2c_sw_master_getAck
(
void
)
{
uint8_t
retVal
;
i2c_sw_master_setDC
(
m_nLastSDA
,
0
);
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
1
,
1
);
i2c_sw_master_wait
(
5
);
retVal
=
i2c_sw_master_getDC
();
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
return
retVal
;
}
/******************************************************************************
* FunctionName : i2c_sw_master_checkAck
* Description : get dev response
* Parameters : NONE
* Returns : true : get ack ; false : get nack
*******************************************************************************/
bool
i2c_sw_master_checkAck
(
void
)
{
if
(
i2c_sw_master_getAck
())
{
return
false
;
}
else
{
return
true
;
}
}
/******************************************************************************
* FunctionName : i2c_sw_master_send_ack
* Description : response ack
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_send_ack
(
void
)
{
i2c_sw_master_setAck
(
0x0
);
}
/******************************************************************************
* FunctionName : i2c_sw_master_send_nack
* Description : response nack
* Parameters : NONE
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_send_nack
(
void
)
{
i2c_sw_master_setAck
(
0x1
);
}
/******************************************************************************
* FunctionName : i2c_sw_master_readByte
* Description : read Byte from i2c bus
* Parameters : NONE
* Returns : uint8_t - readed value
*******************************************************************************/
uint8_t
i2c_sw_master_readByte
(
void
)
{
uint8_t
retVal
=
0
;
uint8_t
k
,
i
;
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
m_nLastSDA
,
0
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 0
for
(
i
=
0
;
i
<
8
;
i
++
)
{
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 0
i2c_sw_master_setDC
(
1
,
1
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 1
k
=
i2c_sw_master_getDC
();
i2c_sw_master_wait
(
5
);
if
(
i
==
7
)
{
i2c_sw_master_wait
(
3
);
}
k
<<=
(
7
-
i
);
retVal
|=
k
;
}
i2c_sw_master_setDC
(
1
,
0
);
i2c_sw_master_wait
(
5
);
// sda 1, scl 0
return
retVal
;
}
/******************************************************************************
* FunctionName : i2c_sw_master_writeByte
* Description : write wrdata value(one byte) into i2c
* Parameters : uint8_t wrdata - write value
* Returns : NONE
*******************************************************************************/
void
i2c_sw_master_writeByte
(
uint8_t
wrdata
)
{
uint8_t
dat
;
int8_t
i
;
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
m_nLastSDA
,
0
);
i2c_sw_master_wait
(
5
);
for
(
i
=
7
;
i
>=
0
;
i
--
)
{
dat
=
wrdata
>>
i
;
i2c_sw_master_setDC
(
dat
,
0
);
i2c_sw_master_wait
(
5
);
i2c_sw_master_setDC
(
dat
,
1
);
i2c_sw_master_wait
(
5
);
if
(
i
==
0
)
{
i2c_sw_master_wait
(
3
);
}
i2c_sw_master_setDC
(
dat
,
0
);
i2c_sw_master_wait
(
5
);
}
}
components/driver_i2c/include/driver/i2c_sw_master.h
0 → 100644
View file @
381726f1
#ifndef __I2C_SW_MASTER_H__
#define __I2C_SW_MASTER_H__
#include "rom/ets_sys.h"
#define I2C_NUM_MAX 1
void
i2c_sw_master_gpio_init
(
uint8
sda
,
uint8
scl
);
void
i2c_sw_master_init
(
void
);
#define i2c_sw_master_wait ets_delay_us
void
i2c_sw_master_stop
(
void
);
void
i2c_sw_master_start
(
void
);
void
i2c_sw_master_setAck
(
uint8_t
level
);
uint8_t
i2c_sw_master_getAck
(
void
);
uint8_t
i2c_sw_master_readByte
(
void
);
void
i2c_sw_master_writeByte
(
uint8_t
wrdata
);
bool
i2c_sw_master_checkAck
(
void
);
void
i2c_sw_master_send_ack
(
void
);
void
i2c_sw_master_send_nack
(
void
);
uint8_t
i2c_sw_master_get_pinSDA
();
uint8_t
i2c_sw_master_get_pinSCL
();
#endif
components/modules/Kconfig
View file @
381726f1
...
...
@@ -79,6 +79,12 @@ config LUA_MODULE_GPIO
help
Includes the GPIO module (recommended).
config LUA_MODULE_I2C
bool "I2C module"
default "y"
help
Includes the I2C module (recommended).
config LUA_MODULE_NET
bool "Net module"
default "y"
...
...
components/modules/i2c.c
0 → 100644
View file @
381726f1
// Module for interfacing with the I2C interface
#include "module.h"
#include "lauxlib.h"
#include "platform.h"
// Lua: i2c.setup( id, sda, scl, speed )
static
int
i2c_setup
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
unsigned
sda
=
luaL_checkinteger
(
L
,
2
);
unsigned
scl
=
luaL_checkinteger
(
L
,
3
);
MOD_CHECK_ID
(
i2c
,
id
);
MOD_CHECK_ID
(
gpio
,
sda
);
MOD_CHECK_ID
(
gpio
,
scl
);
int32_t
speed
=
(
int32_t
)
luaL_checkinteger
(
L
,
4
);
luaL_argcheck
(
L
,
speed
>
0
,
4
,
"wrong arg range"
);
if
(
!
platform_i2c_setup
(
id
,
sda
,
scl
,
(
uint32_t
)
speed
))
luaL_error
(
L
,
"setup failed"
);
return
0
;
}
// Lua: i2c.start( id )
static
int
i2c_start
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
MOD_CHECK_ID
(
i2c
,
id
);
if
(
!
platform_i2c_send_start
(
id
))
luaL_error
(
L
,
"command failed"
);
return
0
;
}
// Lua: i2c.stop( id )
static
int
i2c_stop
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
MOD_CHECK_ID
(
i2c
,
id
);
if
(
!
platform_i2c_send_stop
(
id
))
luaL_error
(
L
,
"command failed"
);
return
0
;
}
// Lua: status = i2c.address( id, address, direction )
static
int
i2c_address
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
int
address
=
luaL_checkinteger
(
L
,
2
);
int
direction
=
luaL_checkinteger
(
L
,
3
);
MOD_CHECK_ID
(
i2c
,
id
);
luaL_argcheck
(
L
,
address
>=
0
&&
address
<=
127
,
2
,
"wrong arg range"
);
int
ret
=
platform_i2c_send_address
(
id
,
(
uint16_t
)
address
,
direction
,
1
);
lua_pushboolean
(
L
,
ret
>
0
);
return
1
;
}
// Lua: wrote = i2c.write( id, data1, [data2], ..., [datan] )
// data can be either a string, a table or an 8-bit number
static
int
i2c_write
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
const
char
*
pdata
;
size_t
datalen
,
i
;
int
numdata
;
uint32_t
wrote
=
0
;
unsigned
argn
;
MOD_CHECK_ID
(
i2c
,
id
);
if
(
lua_gettop
(
L
)
<
2
)
return
luaL_error
(
L
,
"wrong arg type"
);
for
(
argn
=
2
;
argn
<=
lua_gettop
(
L
);
argn
++
)
{
// lua_isnumber() would silently convert a string of digits to an integer
// whereas here strings are handled separately.
if
(
lua_type
(
L
,
argn
)
==
LUA_TNUMBER
)
{
numdata
=
(
int
)
luaL_checkinteger
(
L
,
argn
);
if
(
numdata
<
0
||
numdata
>
255
)
return
luaL_error
(
L
,
"wrong arg range"
);
if
(
platform_i2c_send_byte
(
id
,
numdata
,
1
)
!=
1
)
break
;
wrote
++
;
}
else
if
(
lua_istable
(
L
,
argn
)
)
{
datalen
=
lua_objlen
(
L
,
argn
);
for
(
i
=
0
;
i
<
datalen
;
i
++
)
{
lua_rawgeti
(
L
,
argn
,
i
+
1
);
numdata
=
(
int
)
luaL_checkinteger
(
L
,
-
1
);
lua_pop
(
L
,
1
);
if
(
numdata
<
0
||
numdata
>
255
)
return
luaL_error
(
L
,
"wrong arg range"
);
if
(
platform_i2c_send_byte
(
id
,
numdata
,
1
)
==
0
)
break
;
}
wrote
+=
i
;
if
(
i
<
datalen
)
break
;
}
else
{
pdata
=
luaL_checklstring
(
L
,
argn
,
&
datalen
);
for
(
i
=
0
;
i
<
datalen
;
i
++
)
if
(
platform_i2c_send_byte
(
id
,
pdata
[
i
],
1
)
==
0
)
break
;
wrote
+=
i
;
if
(
i
<
datalen
)
break
;
}
}
lua_pushinteger
(
L
,
wrote
);
return
1
;
}
// Lua: read = i2c.read( id, size )
static
int
i2c_read
(
lua_State
*
L
)
{
unsigned
id
=
luaL_checkinteger
(
L
,
1
);
uint32_t
size
=
(
uint32_t
)
luaL_checkinteger
(
L
,
2
),
i
;
luaL_Buffer
b
;
int
data
;
MOD_CHECK_ID
(
i2c
,
id
);
if
(
size
==
0
)
return
0
;
luaL_buffinit
(
L
,
&
b
);
for
(
i
=
0
;
i
<
size
;
i
++
)
if
(
(
data
=
platform_i2c_recv_byte
(
id
,
i
<
size
-
1
)
)
==
-
1
)
break
;
else
luaL_addchar
(
&
b
,
(
char
)
data
);
luaL_pushresult
(
&
b
);
return
1
;
}
static
const
LUA_REG_TYPE
i2c_map
[]
=
{
{
LSTRKEY
(
"setup"
),
LFUNCVAL
(
i2c_setup
)
},
{
LSTRKEY
(
"start"
),
LFUNCVAL
(
i2c_start
)
},
{
LSTRKEY
(
"stop"
),
LFUNCVAL
(
i2c_stop
)
},
{
LSTRKEY
(
"address"
),
LFUNCVAL
(
i2c_address
)
},
{
LSTRKEY
(
"write"
),
LFUNCVAL
(
i2c_write
)
},
{
LSTRKEY
(
"read"
),
LFUNCVAL
(
i2c_read
)
},
{
LSTRKEY
(
"FAST"
),
LNUMVAL
(
PLATFORM_I2C_SPEED_FAST
)
},
{
LSTRKEY
(
"SLOW"
),
LNUMVAL
(
PLATFORM_I2C_SPEED_SLOW
)
},
{
LSTRKEY
(
"TRANSMITTER"
),
LNUMVAL
(
PLATFORM_I2C_DIRECTION_TRANSMITTER
)
},
{
LSTRKEY
(
"RECEIVER"
),
LNUMVAL
(
PLATFORM_I2C_DIRECTION_RECEIVER
)
},
{
LNILKEY
,
LNILVAL
}
};
NODEMCU_MODULE
(
I2C
,
"i2c"
,
i2c_map
,
NULL
);
components/platform/include/platform.h
View file @
381726f1
...
...
@@ -34,6 +34,13 @@ enum
int
platform_init
(
void
);
// *****************************************************************************
// GPIO subsection
int
platform_gpio_exists
(
unsigned
gpio
);
int
platform_gpio_output_exists
(
unsigned
gpio
);
// *****************************************************************************
// UART subsection
...
...
@@ -80,6 +87,33 @@ uint8_t platform_sigma_delta_set_prescale( uint8_t channel, uint8_t prescale );
uint8_t
platform_sigma_delta_set_duty
(
uint8_t
channel
,
int8_t
duty
);
// *****************************************************************************
// I2C platform interface
// I2C speed
enum
{
PLATFORM_I2C_SPEED_SLOW
=
100000
,
PLATFORM_I2C_SPEED_FAST
=
400000
};
// I2C direction
enum
{
PLATFORM_I2C_DIRECTION_TRANSMITTER
,
PLATFORM_I2C_DIRECTION_RECEIVER
};
int
platform_i2c_exists
(
unsigned
id
);
int
platform_i2c_setup
(
unsigned
id
,
uint8_t
sda
,
uint8_t
scl
,
uint32_t
speed
);
int
platform_i2c_send_start
(
unsigned
id
);
int
platform_i2c_send_stop
(
unsigned
id
);
int
platform_i2c_send_address
(
unsigned
id
,
uint16_t
address
,
int
direction
,
int
ack_check_en
);
int
platform_i2c_send_byte
(
unsigned
id
,
uint8_t
data
,
int
ack_check_en
);
// ack_val: 1 = send ACK, 0 = send NACK
int
platform_i2c_recv_byte
(
unsigned
id
,
int
ack_val
);
// Internal flash erase/write functions
uint32_t
platform_flash_get_sector_of_address
(
uint32_t
addr
);
...
...
components/platform/platform.c
View file @
381726f1
...
...
@@ -8,6 +8,14 @@ int platform_init (void)
return
PLATFORM_OK
;
}
// *****************************************************************************
// GPIO subsection
int
platform_gpio_exists
(
unsigned
gpio
)
{
return
GPIO_IS_VALID_GPIO
(
gpio
);
}
int
platform_gpio_output_exists
(
unsigned
gpio
)
{
return
GPIO_IS_VALID_OUTPUT_GPIO
(
gpio
);
}
// ****************************************************************************
// UART
...
...
@@ -138,3 +146,149 @@ uint8_t IRAM_ATTR platform_sigma_delta_set_duty( uint8_t channel, int8_t duty )
{
return
ESP_OK
==
sigmadelta_set_duty
(
channel
,
duty
)
?
1
:
0
;
}
// *****************************************************************************
// I2C platform interface
#if 0
// platform functions for the IDF I2C driver
// they're currently deactivated because of https://github.com/espressif/esp-idf/issues/241
// long-term goal is to use these instead of the SW driver in the #else branch
#include "driver/i2c.h"
int platform_i2c_setup( unsigned id, uint8_t sda, uint8_t scl, uint32_t speed ) {
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = sda;
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = scl;
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = speed;
if (ESP_OK != i2c_param_config( id, &conf ))
return 0;
if (ESP_OK != i2c_driver_install( id, conf.mode, 0, 0, 0 ))
return 0;
return 1;
}
int platform_i2c_send_start( unsigned id ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_start( cmd );
esp_err_t ret = i2c_master_cmd_begin( id, cmd, 1000 / portTICK_RATE_MS );
i2c_cmd_link_delete( cmd );
return ret == ESP_OK ? 1 : 0;
}
int platform_i2c_send_stop( unsigned id ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_stop( cmd );
esp_err_t ret = i2c_master_cmd_begin( id, cmd, 1000 / portTICK_RATE_MS );
i2c_cmd_link_delete( cmd );
return ret == ESP_OK ? 1 : 0;
}
int platform_i2c_send_address( unsigned id, uint16_t address, int direction, int ack_check_en ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
direction = ( direction == PLATFORM_I2C_DIRECTION_TRANSMITTER ) ? 0 : 1;
i2c_master_write_byte( cmd, (uint8_t) ((address << 1) | direction ), ack_check_en );
esp_err_t ret = i2c_master_cmd_begin( id, cmd, 1000 / portTICK_RATE_MS );
i2c_cmd_link_delete( cmd );
// we return ack (1=acked).
if (ret == ESP_FAIL)
return 0;
else if (ret == ESP_OK)
return 1;
else
return -1;
}
int platform_i2c_send_byte( unsigned id, uint8_t data, int ack_check_en ) {
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_write_byte( cmd, data, ack_check_en );
esp_err_t ret = i2c_master_cmd_begin( id, cmd, 1000 / portTICK_RATE_MS );
i2c_cmd_link_delete( cmd );
// we return ack (1=acked).
if (ret == ESP_FAIL)
return 0;
else if (ret == ESP_OK)
return 1;
else
return -1;
}
int platform_i2c_recv_byte( unsigned id, int ack_val ){
uint8_t data;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
i2c_master_read_byte( cmd, &data, ack_val > 0 ? 0 : 1 );
esp_err_t ret = i2c_master_cmd_begin( id, cmd, 1000 / portTICK_RATE_MS );
i2c_cmd_link_delete( cmd );
return ret == ESP_OK ? data : -1;
}
#else
// platform functions for SW-based I2C driver
// they work around the issue with the IDF driver
// remove when functions for the IDF driver can be used instead
#include "driver/i2c_sw_master.h"
int
platform_i2c_setup
(
unsigned
id
,
uint8_t
sda
,
uint8_t
scl
,
uint32_t
speed
){
if
(
!
platform_gpio_output_exists
(
sda
)
||
!
platform_gpio_output_exists
(
scl
))
return
0
;
if
(
speed
!=
PLATFORM_I2C_SPEED_SLOW
)
return
0
;
i2c_sw_master_gpio_init
(
sda
,
scl
);
return
1
;
}
int
platform_i2c_send_start
(
unsigned
id
){
i2c_sw_master_start
();
return
1
;
}
int
platform_i2c_send_stop
(
unsigned
id
){
i2c_sw_master_stop
();
return
1
;
}
int
platform_i2c_send_address
(
unsigned
id
,
uint16_t
address
,
int
direction
,
int
ack_check_en
){
// Convert enum codes to R/w bit value.
// If TX == 0 and RX == 1, this test will be removed by the compiler
if
(
!
(
PLATFORM_I2C_DIRECTION_TRANSMITTER
==
0
&&
PLATFORM_I2C_DIRECTION_RECEIVER
==
1
)
)
{
direction
=
(
direction
==
PLATFORM_I2C_DIRECTION_TRANSMITTER
)
?
0
:
1
;
}
i2c_sw_master_writeByte
(
(
uint8_t
)
((
address
<<
1
)
|
direction
));
// Low-level returns nack (0=acked); we return ack (1=acked).
return
!
i2c_sw_master_getAck
();
}
int
platform_i2c_send_byte
(
unsigned
id
,
uint8_t
data
,
int
ack_check_en
){
i2c_sw_master_writeByte
(
data
);
// Low-level returns nack (0=acked); we return ack (1=acked).
return
!
i2c_sw_master_getAck
();
}
int
platform_i2c_recv_byte
(
unsigned
id
,
int
ack
){
uint8_t
r
=
i2c_sw_master_readByte
();
i2c_sw_master_setAck
(
!
ack
);
return
r
;
}
#endif
int
platform_i2c_exists
(
unsigned
id
)
{
return
id
<
I2C_NUM_MAX
;
}
docs/en/modules/i2c.md
0 → 100644
View file @
381726f1
# I²C Module
| Since | Origin / Contributor | Maintainer | Source |
| :----- | :-------------------- | :---------- | :------ |
| 2014-12-22 |
[
Zeroday
](
https://github.com/funshine
)
|
[
Zeroday
](
https://github.com/funshine
)
|
[
i2c.c
](
../../../app/modules/i2c.c
)
|
## i2c.address()
Setup I²C address and read/write mode for the next transfer.
#### Syntax
`i2c.address(id, device_addr, direction)`
#### Parameters
-
`id`
always 0
-
`device_addr`
device address
-
`direction`
`i2c.TRANSMITTER`
for writing mode ,
`i2c. RECEIVER`
for reading mode
#### Returns
`true`
if ack received,
`false`
if no ack received.
#### See also
[
i2c.read()
](
#i2cread
)
## i2c.read()
Read data for variable number of bytes.
#### Syntax
`i2c.read(id, len)`
#### Parameters
-
`id`
always 0
-
`len`
number of data bytes
#### Returns
`string`
of received data
#### Example
```
lua
id
=
0
sda
=
1
scl
=
2
-- initialize i2c, set pin1 as sda, set pin2 as scl
i2c
.
setup
(
id
,
sda
,
scl
,
i2c
.
SLOW
)
-- user defined function: read from reg_addr content of dev_addr
function
read_reg
(
dev_addr
,
reg_addr
)
i2c
.
start
(
id
)
i2c
.
address
(
id
,
dev_addr
,
i2c
.
TRANSMITTER
)
i2c
.
write
(
id
,
reg_addr
)
i2c
.
stop
(
id
)
i2c
.
start
(
id
)
i2c
.
address
(
id
,
dev_addr
,
i2c
.
RECEIVER
)
c
=
i2c
.
read
(
id
,
1
)
i2c
.
stop
(
id
)
return
c
end
-- get content of register 0xAA of device 0x77
reg
=
read_reg
(
0x77
,
0xAA
)
print
(
string.byte
(
reg
))
```
####See also
[
i2c.write()
](
#i2cwrite
)
## i2c.setup()
Initialize the I²C module.
#### Syntax
`i2c.setup(id, pinSDA, pinSCL, speed)`
####Parameters
-
`id`
always 0
-
`pinSDA`
1~12, IO index
-
`pinSCL`
1~12, IO index
-
`speed`
only
`i2c.SLOW`
supported
#### Returns
`speed`
the selected speed
####See also
[
i2c.read()
](
#i2cread
)
## i2c.start()
Send an I²C start condition.
#### Syntax
`i2c.start(id)`
#### Parameters
`id`
always 0
#### Returns
`nil`
####See also
[
i2c.read()
](
#i2cread
)
## i2c.stop()
Send an I²C stop condition.
#### Syntax
`i2c.stop(id)`
####Parameters
`id`
always 0
#### Returns
`nil`
####See also
[
i2c.read()
](
#i2cread
)
## i2c.write()
Write data to I²C bus. Data items can be multiple numbers, strings or lua tables.
####Syntax
`i2c.write(id, data1[, data2[, ..., datan]])`
####Parameters
-
`id`
always 0
-
`data`
data can be numbers, string or lua table.
#### Returns
`number`
number of bytes written
#### Example
```
lua
i2c
.
write
(
0
,
"hello"
,
"world"
)
```
#### See also
[
i2c.read()
](
#i2cread
)
mkdocs.yml
View file @
381726f1
...
...
@@ -33,6 +33,7 @@ pages:
-
'
bit'
:
'
en/modules/bit.md'
-
'
bthci'
:
'
en/modules/bthci.md'
-
'
file'
:
'
en/modules/file.md'
-
'
i2c'
:
'
en/modules/i2c.md'
-
'
node'
:
'
en/modules/node.md'
-
'
sigma
delta'
:
'
en/modules/sigma-delta.md'
-
'
struct'
:
'
en/modules/struct.md'
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment