add i2c module
This commit is contained in:
parent
4fcb1404b6
commit
381726f103
|
@ -0,0 +1 @@
|
|||
COMPONENT_ADD_INCLUDEDIRS:=include
|
|
@ -0,0 +1,314 @@
|
|||
/******************************************************************************
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#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
|
|
@ -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"
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
// 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);
|
|
@ -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 );
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
# 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)
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue