Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
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