2017-01-06 21:04:22 +13:00

233 lines
6.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* This file is designed to support i2c functions in Espruino,
* a JavaScript interpreter for Microcontrollers designed by Gordon Williams
*
* Copyright (C) 2016 by Rhys Williams (wilberforce)
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* ----------------------------------------------------------------------------
* This file is designed to be parsed during the build process
*
* Contains ESP32 board specific functions.
* ----------------------------------------------------------------------------
*/
//#include "esp_log.h"
#include "i2c.h"
// Switch while debugging native i2c code - comment out to use native
//#define USE_ARDUINO
#ifdef USE_ARDUINO
// Using arduino library
#include "esp32-hal-i2c.h"
#endif
#ifndef USE_ARDUINO
#include "driver/i2c.h"
#endif
#ifndef USE_ARDUINO
#define I2C_MASTER_NUM I2C_NUM_1 /*!< I2C port number for master dev */
#define I2C_MASTER_TX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_RX_BUF_DISABLE 0 /*!< I2C master do not need buffer */
#define I2C_MASTER_FREQ_HZ 100000 /*!< I2C master clock frequency */
#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/
#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */
#define ACK_VAL 0x0 /*!< I2C ack value */
#define NACK_VAL 0x1 /*!< I2C nack value */
// Let's get this working with only one device
/* To do:
support both i2c ports
Test!
Stop bits param - bool sendStop
https://esp-idf.readthedocs.io/en/latest/api/i2c.html
*/
static esp_err_t checkError( char * caller, esp_err_t ret ) {
switch(ret) {
case ESP_OK: break;
case ESP_ERR_INVALID_ARG: {
jsError( "%s:, Parameter error\n", caller );
break;
}
case ESP_FAIL: {
jsError( "%s:, slave doesnt ACK the transfer.\n", caller );
break;
}
case ESP_ERR_TIMEOUT: {
jsError( "%s:, Operation timeout because the bus is busy.\n", caller );
break;
}
default: {
jsError( "%s:, unknown error code %d, \n", caller, ret );
break;
}
}
return ret;
}
int getI2cFromDevice( IOEventFlags device ) {
switch(device) {
case EV_I2C1: return I2C_NUM_0;
case EV_I2C2: return I2C_NUM_1;
default: return -1;
}
}
/** Set-up I2C master for ESP32, default pins are SCL:21, SDA:22. Only device I2C1 is supported
* and only master mode. */
void jshI2CSetup(IOEventFlags device, JshI2CInfo *info) {
int i2c_master_port = getI2cFromDevice(device);
if (i2c_master_port == -1) {
jsError("Only I2C1 and I2C2 supported");
return;
}
Pin scl;
Pin sda;
if ( i2c_master_port == I2C_NUM_0 ) {
scl = info->pinSCL != PIN_UNDEFINED ? info->pinSCL : 21;
sda = info->pinSDA != PIN_UNDEFINED ? info->pinSDA : 22;
}
// Unsure on what to default these pins to?
if ( i2c_master_port == I2C_NUM_1 ) {
scl = info->pinSCL != PIN_UNDEFINED ? info->pinSCL : 16;
sda = info->pinSDA != PIN_UNDEFINED ? info->pinSDA : 17;
}
i2c_config_t conf;
conf.mode = I2C_MODE_MASTER;
conf.sda_io_num = pinToESP32Pin(sda);
conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
conf.scl_io_num = pinToESP32Pin(scl);
conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
conf.master.clk_speed = info->bitrate;
esp_err_t err=i2c_param_config(i2c_master_port, &conf);
if ( err == ESP_ERR_INVALID_ARG ) {
jsError("jshI2CSetup: Invalid arguments");
return;
}
err=i2c_driver_install(i2c_master_port, conf.mode, 0, 0, 0);
if ( err == ESP_OK ) {
jsError("jshI2CSetup: driver installed, sda: %d sdl: %d freq: %d, \n", sda, scl, info->bitrate);
} else {
checkError("jshI2CSetup",err);
}
}
void jshI2CWrite(IOEventFlags device,
unsigned char address,
int nBytes,
const unsigned char *data,
bool sendStop) {
esp_err_t ret;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ret=i2c_master_start(cmd);
ret=i2c_master_write_byte(cmd, address << 1 | I2C_MASTER_WRITE, ACK_CHECK_EN);
ret=i2c_master_write(cmd, data, nBytes, ACK_CHECK_EN);
ret=i2c_master_stop(cmd);
int i2c_master_port = I2C_NUM_1;
ret = i2c_master_cmd_begin(i2c_master_port, cmd, 1000 / portTICK_RATE_MS); // 1000 seems very large for ticks_to_wait???
i2c_cmd_link_delete(cmd);
checkError( "jshI2CWrite", ret);
}
void jshI2CRead(IOEventFlags device,
unsigned char address,
int nBytes,
unsigned char *data,
bool sendStop) {
if (nBytes <= 0) {
return;
}
esp_err_t ret;
int i2c_master_port = I2C_NUM_1;
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
ret=i2c_master_start(cmd);
ret=i2c_master_write_byte(cmd, ( i2c_master_port << 1 ) | I2C_MASTER_READ, ACK_CHECK_EN);
if (nBytes > 1) {
ret=i2c_master_read(cmd, data, nBytes - 1, ACK_VAL);
}
ret=i2c_master_read_byte(cmd, data + nBytes - 1, NACK_VAL);
i2c_master_stop(cmd);
ret = i2c_master_cmd_begin(i2c_master_port, cmd, 1000 / portTICK_RATE_MS);
i2c_cmd_link_delete(cmd);
checkError( "jshI2CRead", ret);
}
#endif
#ifdef USE_ARDUINO
// Let's get this working with only one device
i2c_t * i2c=NULL;
/** Set-up I2C master for ESP32, default pins are SCL:21, SDA:22. Only device I2C1 is supported
* and only master mode. */
vxoid jshI2CSetup(IOEventFlags device, JshI2CInfo *info) {
if (device != EV_I2C1) {
jsError("Only I2C1 supported");
return;
}
Pin scl = info->pinSCL != PIN_UNDEFINED ? info->pinSCL : 21;
Pin sda = info->pinSDA != PIN_UNDEFINED ? info->pinSDA : 22;
//jshPinSetState(scl, JSHPINSTATE_I2C);
//jshPinSetState(sda, JSHPINSTATE_I2C);
int num=1; // Master mode only 0 is slave mode..
i2c_err_t err;
i2c = i2cInit(num, 0, false);
//jsError("jshI2CSetup: Frequency: %d", info->bitrate);
err=i2cSetFrequency(i2c, (uint32_t)info->bitrate);
if ( err != I2C_ERROR_OK ) {
jsError( "jshI2CSetup: i2cSetFrequency error: %d", err);
return;
}
err=i2cAttachSDA(i2c, pinToESP32Pin(sda));
if ( err != I2C_ERROR_OK ) {
jsError( "jshI2CSetup: i2cAttachSDA error: %d", err);
return;
}
err=i2cAttachSCL(i2c, pinToESP32Pin(scl));
if ( err != I2C_ERROR_OK ) {
jsError( "jshI2CSetup: i2cAttachSCL error: %d", err);
return;
}
}
void jshI2CWrite(IOEventFlags device,
unsigned char address,
int nBytes,
const unsigned char *data,
bool sendStop) {
// i2cWrite(i2c_t * i2c, uint16_t address, bool addr_10bit, uint8_t * data, uint8_t len, bool sendStop);
i2c_err_t err=i2cWrite(i2c,address,false,data,nBytes,sendStop);
if ( err != I2C_ERROR_OK ) {
jsError( "jshI2CSetup: i2cAttachSCL error: %d", err);
return;
}
}
void jshI2CRead(IOEventFlags device,
unsigned char address,
int nBytes,
unsigned char *data,
bool sendStop) {
i2c_err_t err=i2cRead(i2c,address,false,data,nBytes,sendStop);
if ( err != I2C_ERROR_OK ) {
jsError( "jshI2CSetup: i2cAttachSCL error: %d", err);
return;
}
}
#endif