Skip to content

Commit

Permalink
< contiki-os#2599 [lavr18-add-cc26-i2c] - Add board-i2c library for t…
Browse files Browse the repository at this point in the history
…he launchpad

--HG--
branch : alexrayne_works
  • Loading branch information
alexrayne committed Dec 25, 2019
2 parents a6c1a91 + f5aa1b1 commit a810628
Show file tree
Hide file tree
Showing 6 changed files with 536 additions and 81 deletions.
22 changes: 11 additions & 11 deletions platform/apple2enh/Makefile.apple2enh
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,19 @@ endif

disk: all
cp $(CONTIKI)/tools/$(TARGET)/prodos.dsk contiki.dsk
java -jar $(AC) -p contiki.dsk contiki.system sys < $(CC65_TARGET_DIR)/util/loader.system
java -jar $(AC) -cc65 contiki.dsk contiki bin < $(CONTIKI_PROJECT).$(TARGET)
java -jar $(AC) -p contiki.dsk contiki.system sys < $(CC65_TARGET_DIR)/util/loader.system
java -jar $(AC) -as contiki.dsk contiki < $(CONTIKI_PROJECT).$(TARGET)
ifdef SLIP
java -jar $(AC) -p contiki.dsk contiki.cfg bin 0 < $(CONTIKI)/tools/6502/sample.cfg
java -jar $(AC) -p contiki.dsk contiki.cfg bin 0 < $(CONTIKI)/tools/6502/sample.cfg
else
java -jar $(AC) -p contiki.dsk contiki.cfg bin 0 < $(CONTIKI)/tools/$(TARGET)/sample.cfg
java -jar $(AC) -p contiki.dsk cs8900a.eth rel 0 < cs8900a.eth
java -jar $(AC) -p contiki.dsk lan91c96.eth rel 0 < lan91c96.eth
java -jar $(AC) -p contiki.dsk w5100.eth rel 0 < w5100.eth
java -jar $(AC) -p contiki.dsk contiki.cfg bin 0 < $(CONTIKI)/tools/$(TARGET)/sample.cfg
java -jar $(AC) -p contiki.dsk cs8900a.eth rel 0 < cs8900a.eth
java -jar $(AC) -p contiki.dsk lan91c96.eth rel 0 < lan91c96.eth
java -jar $(AC) -p contiki.dsk w5100.eth rel 0 < w5100.eth
endif
ifeq ($(HTTPD-CFS),1)
java -jar $(AC) -p contiki.dsk index.htm bin 0 < httpd-cfs/index.htm
java -jar $(AC) -p contiki.dsk backgrnd.gif bin 0 < httpd-cfs/backgrnd.gif
java -jar $(AC) -p contiki.dsk contiki.gif bin 0 < httpd-cfs/contiki.gif
java -jar $(AC) -p contiki.dsk notfound.htm bin 0 < httpd-cfs/notfound.htm
java -jar $(AC) -p contiki.dsk index.htm bin 0 < httpd-cfs/index.htm
java -jar $(AC) -p contiki.dsk backgrnd.gif bin 0 < httpd-cfs/backgrnd.gif
java -jar $(AC) -p contiki.dsk contiki.gif bin 0 < httpd-cfs/contiki.gif
java -jar $(AC) -p contiki.dsk notfound.htm bin 0 < httpd-cfs/notfound.htm
endif
2 changes: 1 addition & 1 deletion platform/srf06-cc26xx/launchpad/Makefile.launchpad
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ CFLAGS += -DBOARD_LAUNCHPAD=1
CONTIKI_TARGET_DIRS += launchpad common

BOARD_SOURCEFILES += board.c launchpad-sensors.c leds-arch.c button-sensor.c
BOARD_SOURCEFILES += ext-flash.c board-spi.c
BOARD_SOURCEFILES += ext-flash.c board-spi.c board-i2c.c

### Signal that we can be programmed with cc2538-bsl
BOARD_SUPPORTS_BSL=1
323 changes: 323 additions & 0 deletions platform/srf06-cc26xx/launchpad/board-i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
/*
* Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
* Copyright (c) 2017, University of Bristol - http://www.bris.ac.uk/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*---------------------------------------------------------------------------*/
/**
* \addtogroup sensortag-cc26xx-i2c
* @{
*
* \file
* Board-specific I2C driver for the Sensortags
*/
/*---------------------------------------------------------------------------*/
#include "contiki-conf.h"
#include "ti-lib.h"
#include "board-i2c.h"
#include "lpm.h"
#include "rtimer.h"

#include <string.h>
#include <stdbool.h>
/*---------------------------------------------------------------------------*/
#define I2C_MAX_WAIT_TIME (RTIMER_SECOND / 10)

#define LIMITED_BUSYWAIT(cond) do { \
rtimer_clock_t end_time = RTIMER_NOW() + I2C_MAX_WAIT_TIME; \
while(cond) { \
if(!RTIMER_CLOCK_LT(RTIMER_NOW(), end_time)) { \
return false; \
} \
} \
} while(0)
/*---------------------------------------------------------------------------*/
#define NO_INTERFACE 0xFF
/*---------------------------------------------------------------------------*/
static uint8_t slave_addr = 0x00;
static uint8_t interface = NO_INTERFACE;
/*---------------------------------------------------------------------------*/
static bool
accessible(void)
{
/* First, check the PD */
if(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
!= PRCM_DOMAIN_POWER_ON) {
return false;
}

/* Then check the 'run mode' clock gate */
if(!(HWREG(PRCM_BASE + PRCM_O_I2CCLKGR) & PRCM_I2CCLKGR_CLK_EN)) {
return false;
}

return true;
}
/*---------------------------------------------------------------------------*/
void
board_i2c_wakeup()
{
/* First, make sure the SERIAL PD is on */
ti_lib_prcm_power_domain_on(PRCM_DOMAIN_SERIAL);
while((ti_lib_prcm_power_domain_status(PRCM_DOMAIN_SERIAL)
!= PRCM_DOMAIN_POWER_ON));

/* Enable the clock to I2C */
ti_lib_prcm_peripheral_run_enable(PRCM_PERIPH_I2C0);
ti_lib_prcm_load_set();
while(!ti_lib_prcm_load_get());

/* Enable and initialize the I2C master module */
ti_lib_i2c_master_init_exp_clk(I2C0_BASE, ti_lib_sys_ctrl_clock_get(),
true);
}
/*---------------------------------------------------------------------------*/
static bool
i2c_status()
{
uint32_t status;

status = ti_lib_i2c_master_err(I2C0_BASE);
if(status & (I2C_MSTAT_DATACK_N_M | I2C_MSTAT_ADRACK_N_M)) {
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
}

return status == I2C_MASTER_ERR_NONE;
}
/*---------------------------------------------------------------------------*/
void
board_i2c_shutdown()
{
interface = NO_INTERFACE;

if(accessible()) {
ti_lib_i2c_master_disable(I2C0_BASE);
}

ti_lib_prcm_peripheral_run_disable(PRCM_PERIPH_I2C0);
ti_lib_prcm_load_set();
while(!ti_lib_prcm_load_get());

/*
* Set all pins to GPIO Input and disable the output driver. Set internal
* pull to match external pull
*
* SDA and SCL: external PU resistor
*/
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SDA);
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA, IOC_IOPULL_UP);
ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_SCL);
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL, IOC_IOPULL_UP);
}
/*---------------------------------------------------------------------------*/
bool
board_i2c_write(uint8_t *data, uint8_t len)
{
uint32_t i;
bool success;

/* Write slave address */
ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false);

/* Write first byte */
ti_lib_i2c_master_data_put(I2C0_BASE, data[0]);

/* Check if another master has access */
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));

/* Assert RUN + START */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();

for(i = 1; i < len && success; i++) {
/* Write next byte */
ti_lib_i2c_master_data_put(I2C0_BASE, data[i]);
if(i < len - 1) {
/* Clear START */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
}
}

/* Assert stop */
if(success) {
/* Assert STOP */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_FINISH);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));
}

return success;
}
/*---------------------------------------------------------------------------*/
bool
board_i2c_write_single(uint8_t data)
{
/* Write slave address */
ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false);

/* Write first byte */
ti_lib_i2c_master_data_put(I2C0_BASE, data);

/* Check if another master has access */
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));

/* Assert RUN + START + STOP */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));

return i2c_status();
}
/*---------------------------------------------------------------------------*/
bool
board_i2c_read(uint8_t *data, uint8_t len)
{
uint8_t i;
bool success;

/* Set slave address */
ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, true);

/* Check if another master has access */
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));

/* Assert RUN + START + ACK */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

i = 0;
success = true;
while(i < (len - 1) && success) {
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
if(success) {
data[i] = ti_lib_i2c_master_data_get(I2C0_BASE);
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
i++;
}
}

if(success) {
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
if(success) {
data[len - 1] = ti_lib_i2c_master_data_get(I2C0_BASE);
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));
}
}

return success;
}
/*---------------------------------------------------------------------------*/
bool
board_i2c_write_read(uint8_t *wdata, uint8_t wlen, uint8_t *rdata, uint8_t rlen)
{
uint32_t i;
bool success;

/* Set slave address for write */
ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, false);

/* Write first byte */
ti_lib_i2c_master_data_put(I2C0_BASE, wdata[0]);

/* Check if another master has access */
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));

/* Assert RUN + START */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_START);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();

for(i = 1; i < wlen && success; i++) {
/* Write next byte */
ti_lib_i2c_master_data_put(I2C0_BASE, wdata[i]);

/* Clear START */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_SEND_CONT);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
}
if(!success) {
return false;
}

/* Set slave address for read */
ti_lib_i2c_master_slave_addr_set(I2C0_BASE, slave_addr, true);

/* Assert ACK */
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START);

i = 0;
while(i < (rlen - 1) && success) {
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
if(success) {
rdata[i] = ti_lib_i2c_master_data_get(I2C0_BASE);
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_CONT);
i++;
}
}

if(success) {
ti_lib_i2c_master_control(I2C0_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH);
LIMITED_BUSYWAIT(ti_lib_i2c_master_busy(I2C0_BASE));
success = i2c_status();
if(success) {
rdata[rlen - 1] = ti_lib_i2c_master_data_get(I2C0_BASE);
LIMITED_BUSYWAIT(ti_lib_i2c_master_bus_busy(I2C0_BASE));
}
}

return success;
}
/*---------------------------------------------------------------------------*/
void
board_i2c_select(uint8_t address)
{
slave_addr = address;

if(accessible() == false) {
board_i2c_wakeup();
}

ti_lib_i2c_master_disable(I2C0_BASE);

ti_lib_ioc_io_port_pull_set(BOARD_IOID_SDA, IOC_NO_IOPULL);
ti_lib_ioc_io_port_pull_set(BOARD_IOID_SCL, IOC_NO_IOPULL);
ti_lib_ioc_pin_type_i2c(I2C0_BASE, BOARD_IOID_SDA, BOARD_IOID_SCL);

/* Enable and initialize the I2C master module */
ti_lib_i2c_master_init_exp_clk(I2C0_BASE, ti_lib_sys_ctrl_clock_get(),
true);
}
/*---------------------------------------------------------------------------*/
/** @} */
Loading

0 comments on commit a810628

Please sign in to comment.