mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
Merge pull request #6521 from haukepetersen/rm_lpc_i2clma
cpu/drivers: remove deprecated lm75a+lpc2387 I2C drivers
This commit is contained in:
commit
2ef1f2e8f7
@ -1 +0,0 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1,943 +0,0 @@
|
||||
/*
|
||||
* i2c.c - implementation of the I2C interface for the LPC2387 chip.
|
||||
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @internal
|
||||
* @brief The I2C interface drivers for the LPC2387 chip.
|
||||
* The driver is full abstracted supporting all the i2c-interfaces
|
||||
* of the LPC2387 chip. The user need only to give the requested
|
||||
* i2c-interface and the transmission baudrate.
|
||||
* The user can optionally give a master interrupt handler. If the
|
||||
* user does not declare a handler, an appropriate interrupt is
|
||||
* automatically registered for the specific i2c interface.
|
||||
*
|
||||
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
* @author Marco Ziegert <ziegert@inf.fu-berlin.de>
|
||||
* @author Benjamin Aschenbrenner
|
||||
* @version $Revision: 3858 $
|
||||
*
|
||||
* @note $Id: i2c.c 3858 2013-09-02 18:11:17 kasmi $
|
||||
*/
|
||||
|
||||
#include "lpc23xx.h"
|
||||
#include "lpc2387.h"
|
||||
#include "i2c.h"
|
||||
#include "VIC.h"
|
||||
#include "irq.h"
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
volatile uint32_t i2c_master_state = I2C_IDLE;
|
||||
volatile uint32_t i2c_slave_state = I2C_IDLE;
|
||||
volatile uint32_t i2c_cmd;
|
||||
volatile uint32_t i2c_mode;
|
||||
volatile uint8_t i2c_master_buffer[I2C_BUFSIZE];
|
||||
volatile uint32_t i2c_read_length;
|
||||
volatile uint32_t i2c_write_length;
|
||||
volatile uint32_t rd_index = 0;
|
||||
volatile uint32_t wr_index = 0;
|
||||
|
||||
static void i2c_interface0_master_handler(void) __attribute__((interrupt(
|
||||
"IRQ")));
|
||||
static void i2c_interface1_master_handler(void) __attribute__((interrupt(
|
||||
"IRQ")));
|
||||
static void i2c_interface2_master_handler(void) __attribute__((interrupt(
|
||||
"IRQ")));
|
||||
|
||||
bool i2c_initialize(uint8_t i2c_interface, uint32_t i2c_mode,
|
||||
uint8_t slave_addr, uint32_t baud_rate, void *handler)
|
||||
{
|
||||
//puts("i2c_initialize begin...\n");
|
||||
printf("i2cInterface = %d\n", i2c_interface);
|
||||
i2c_clear_buffer((uint8_t *) i2c_master_buffer,
|
||||
I2C_BUFSIZE * sizeof(uint8_t));
|
||||
|
||||
//activate power for I2C2
|
||||
i2c_active_power(i2c_interface);
|
||||
|
||||
//select I2C2 functionality for pins x.xx (SDAx) and x.xx (SCLx)
|
||||
i2c_pin_select(i2c_interface);
|
||||
|
||||
// clear I2CCON register flags
|
||||
i2c_clear_control_register(i2c_interface);
|
||||
|
||||
//set baud rate
|
||||
i2c_set_baud_rate(i2c_interface, baud_rate);
|
||||
|
||||
//set slave mode
|
||||
if (i2c_mode == I2CSLAVE) {
|
||||
i2c_set_slave_mode(i2c_interface, slave_addr);
|
||||
}
|
||||
|
||||
/* Install interrupt handler */
|
||||
if (!i2c_irq_handler_register(i2c_interface, handler)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
i2c_initial_master_transmitter_mode(i2c_interface);
|
||||
|
||||
//puts("...i2c_initialize ended\n");
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool i2c_transaction(uint8_t i2c_interface)
|
||||
{
|
||||
//puts("i2cTransaction begin...\n");
|
||||
i2c_master_state = I2C_IDLE;
|
||||
rd_index = 0;
|
||||
wr_index = 0;
|
||||
|
||||
if (i2c_start(i2c_interface) != true) {
|
||||
i2c_stop(i2c_interface);
|
||||
puts("i2cTransaction return false...\n");
|
||||
return (false);
|
||||
}
|
||||
|
||||
// puts("entering engine main loop\n");
|
||||
while (1) {
|
||||
if (i2c_master_state == DATA_NACK) {
|
||||
i2c_stop(i2c_interface);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// puts("...i2cTransaction ended\n");
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool i2c_start(uint8_t i2c_interface)
|
||||
{
|
||||
// puts("i2c_start begin...\n");
|
||||
uint32_t timeout = 0;
|
||||
bool retVal = false;
|
||||
|
||||
/*--- Issue a start condition ---*/
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
I20CONSET = I2CONSET_STA; /* Set Start flag */
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
I21CONSET = I2CONSET_STA; /* Set Start flag */
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
I22CONSET = I2CONSET_STA; /* Set Start flag */
|
||||
}
|
||||
|
||||
/*--- Wait until START transmitted ---*/
|
||||
while (1) {
|
||||
if (i2c_master_state == I2C_STARTED) {
|
||||
retVal = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (timeout >= MAX_TIMEOUT) {
|
||||
puts("timeout");
|
||||
retVal = false;
|
||||
break;
|
||||
}
|
||||
|
||||
timeout++;
|
||||
}
|
||||
|
||||
//puts("...i2c_start ended\n");
|
||||
return (retVal);
|
||||
}
|
||||
|
||||
bool i2c_stop(uint8_t i2c_interface)
|
||||
{
|
||||
//puts("i2c_stop begin...\n");
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
I20CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
I20CONCLR = I2CONCLR_SIC; /* Clear SI flag */
|
||||
|
||||
/*--- Wait for STOP detected ---*/
|
||||
while (I20CONSET & I2CONSET_STO) {}
|
||||
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
I21CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
I21CONCLR = I2CONCLR_SIC; /* Clear SI flag */
|
||||
|
||||
/*--- Wait for STOP detected ---*/
|
||||
while (I21CONSET & I2CONSET_STO) {}
|
||||
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
I22CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
I22CONCLR = I2CONCLR_SIC; /* Clear SI flag */
|
||||
|
||||
/*--- Wait for STOP detected ---*/
|
||||
while (I22CONSET & I2CONSET_STO) {}
|
||||
}
|
||||
|
||||
// puts("...i2c_stop ended\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
void i2c_active_power(uint8_t i2c_interface)
|
||||
{
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
PCONP |= BIT7;
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
PCONP |= BIT19;
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
PCONP |= BIT26;
|
||||
}
|
||||
}
|
||||
|
||||
//select I2C2 functionality for pins x.xx (SDAx) and x.xx (SCLx)
|
||||
void i2c_pin_select(uint8_t i2cInterface)
|
||||
{
|
||||
switch (i2cInterface) {
|
||||
case I2C0: // P0.27 SDA0, P0.28 SCL0
|
||||
PINSEL1 |= BIT22 | BIT24;
|
||||
PINSEL1 &= ~(BIT23 | BIT25);
|
||||
break;
|
||||
|
||||
case I2C1_0: // P0.0 SDA1, P0.1 SCL1
|
||||
PINSEL0 |= BIT0 | BIT1 | BIT2 | BIT3;
|
||||
break;
|
||||
|
||||
case I2C1_1: // P0.19 SDA1, P0.20 SCL1
|
||||
PINSEL1 |= BIT6 | BIT7 | BIT8 | BIT9;
|
||||
break;
|
||||
|
||||
case I2C2: // P0.10 SDA2, P0.11 SCL2
|
||||
PINSEL0 |= BIT21 | BIT23;
|
||||
PINSEL0 &= ~(BIT20 | BIT22);
|
||||
}
|
||||
}
|
||||
|
||||
/*--- clearing of bits in the I2CON register ---*/
|
||||
void i2c_clear_control_register(uint8_t i2c_interface)
|
||||
{
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
I20CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC |
|
||||
I2CONCLR_I2ENC;
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
I21CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC |
|
||||
I2CONCLR_I2ENC;
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
I22CONCLR = I2CONCLR_AAC | I2CONCLR_SIC | I2CONCLR_STAC |
|
||||
I2CONCLR_I2ENC;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_set_baud_rate(uint8_t i2c_interface, uint32_t baud_rate)
|
||||
{
|
||||
uint32_t pclksel = 0;
|
||||
uint32_t prescale = 0;
|
||||
lpc2387_pclk_scale(CLOCK_CORECLOCK, baud_rate, &pclksel, &prescale);
|
||||
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
PCLKSEL0 &= ~(BIT14 | BIT15); //clear Bits
|
||||
PCLKSEL0 |= pclksel << 14; //set bits
|
||||
|
||||
I20SCLL = prescale / 2;
|
||||
I20SCLH = prescale / 2;
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
PCLKSEL1 &= ~(BIT6 | BIT7);
|
||||
PCLKSEL1 |= pclksel << 6;
|
||||
|
||||
I21SCLL = prescale / 2;
|
||||
I21SCLH = prescale / 2;
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
PCLKSEL1 &= ~(BIT20 | BIT21);
|
||||
PCLKSEL1 |= pclksel << 20;
|
||||
|
||||
I22SCLL = prescale / 2;
|
||||
I22SCLH = prescale / 2;
|
||||
}
|
||||
}
|
||||
|
||||
bool i2c_irq_handler_register(uint8_t i2c_interface, void *handler)
|
||||
{
|
||||
bool successful = false;
|
||||
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
if (handler == NULL) {
|
||||
successful = install_irq(I2C0_INT,
|
||||
(void *) i2c_interface0_master_handler,
|
||||
HIGHEST_PRIORITY);
|
||||
}
|
||||
else {
|
||||
successful = install_irq(I2C0_INT, (void *) handler,
|
||||
HIGHEST_PRIORITY);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
if (handler == NULL) {
|
||||
successful = install_irq(I2C1_INT,
|
||||
(void *) i2c_interface1_master_handler,
|
||||
HIGHEST_PRIORITY);
|
||||
}
|
||||
else {
|
||||
successful = install_irq(I2C1_INT, (void *) handler,
|
||||
HIGHEST_PRIORITY);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
if (handler == NULL) {
|
||||
successful = install_irq(I2C2_INT,
|
||||
(void *) i2c_interface2_master_handler,
|
||||
HIGHEST_PRIORITY);
|
||||
}
|
||||
else {
|
||||
successful = install_irq(I2C2_INT, (void *) handler,
|
||||
HIGHEST_PRIORITY);
|
||||
}
|
||||
}
|
||||
|
||||
return successful;
|
||||
}
|
||||
|
||||
void i2c_initial_master_transmitter_mode(uint8_t i2c_interface)
|
||||
{
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
I20CONSET = I2CONSET_I2EN;
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
I21CONSET = I2CONSET_I2EN;
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
I22CONSET = I2CONSET_I2EN;
|
||||
}
|
||||
}
|
||||
|
||||
bool i2c_read(uint8_t i2c_interface, uint8_t slave_addr, uint8_t reg_addr,
|
||||
uint8_t *rx_buff, uint8_t rx_buff_length)
|
||||
{
|
||||
i2c_clear_buffer((uint8_t *) i2c_master_buffer,
|
||||
I2C_BUFSIZE * sizeof(uint8_t));
|
||||
i2c_write_length = 1;
|
||||
i2c_read_length = rx_buff_length;
|
||||
bool successful;
|
||||
uint8_t readIndex = 3;
|
||||
i2c_master_buffer[0] = (slave_addr << 1) & WRITE_ENABLE_BIT_MASK;
|
||||
i2c_master_buffer[1] = reg_addr;
|
||||
i2c_master_buffer[2] = ((slave_addr << 1) & WRITE_ENABLE_BIT_MASK)
|
||||
| READ_ENABLE_BIT_MASK;
|
||||
successful = i2c_transaction(i2c_interface);
|
||||
|
||||
if (successful && (rx_buff != NULL) &&
|
||||
(rx_buff_length < (I2C_BUFSIZE - readIndex))) {
|
||||
memcpy(rx_buff, (const uint8_t *)(i2c_master_buffer + readIndex),
|
||||
sizeof(uint8_t) * rx_buff_length);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_clear_buffer(void *ptr, uint32_t size)
|
||||
{
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
|
||||
bool i2c_write(uint8_t i2c_interface, uint8_t slave_addr, uint8_t reg_addr,
|
||||
uint8_t *tx_buff, uint8_t tx_buff_length)
|
||||
{
|
||||
//puts("[i2c.c/i2cWrite]: entered\n");
|
||||
i2c_clear_buffer((uint8_t *) i2c_master_buffer,
|
||||
I2C_BUFSIZE * sizeof(uint8_t));
|
||||
i2c_write_length = tx_buff_length + 1;
|
||||
i2c_master_buffer[0] = (slave_addr << 1) & WRITE_ENABLE_BIT_MASK;
|
||||
i2c_master_buffer[1] = reg_addr;
|
||||
|
||||
if ((tx_buff != NULL) && tx_buff_length < (I2C_BUFSIZE - 2)) {
|
||||
int32_t j = 0;
|
||||
for (int32_t i = 2; i < tx_buff_length + 2; i++) {
|
||||
i2c_master_buffer[i] = tx_buff[j];
|
||||
j++;
|
||||
//printf("I2CMasterBuffer[%d] = %d\n", i, I2CMasterBuffer[i]);
|
||||
}
|
||||
|
||||
return i2c_transaction(i2c_interface);
|
||||
}
|
||||
else {
|
||||
puts("[i2c.c/i2cWrite]: Invalid buffer or invalid write buffer size\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//burst mode, the first element in the array
|
||||
bool i2c_trans_receive(uint8_t i2c_interface, uint8_t slave_addr,
|
||||
uint8_t *tx_buff, uint8_t tx_buff_length,
|
||||
uint8_t *rx_buff, uint8_t rx_buff_length)
|
||||
{
|
||||
puts("[i2c.c/i2cTransReceive]: entered\n");
|
||||
i2c_clear_buffer((uint8_t *) i2c_master_buffer,
|
||||
I2C_BUFSIZE * sizeof(uint8_t));
|
||||
i2c_write_length = tx_buff_length;
|
||||
i2c_read_length = rx_buff_length;
|
||||
|
||||
if (tx_buff != NULL && (tx_buff_length > 0)) {
|
||||
int32_t read_index = 0;
|
||||
i2c_master_buffer[0] = (slave_addr << 1) & WRITE_ENABLE_BIT_MASK;
|
||||
|
||||
for (int32_t i = 1; i < tx_buff_length + 1; i++) {
|
||||
if (i < I2C_BUFSIZE) {
|
||||
i2c_master_buffer[i] = tx_buff[i - 1];
|
||||
}
|
||||
}
|
||||
|
||||
//enable I2C to read
|
||||
if ((rx_buff_length > 0) && (i < I2C_BUFSIZE)) {
|
||||
i2c_master_buffer[i] = ((slave_addr << 1) & WRITE_ENABLE_BIT_MASK)
|
||||
| READ_ENABLE_BIT_MASK;
|
||||
read_index = i + 1;
|
||||
}
|
||||
|
||||
bool successful = i2c_transaction(i2c_interface);
|
||||
|
||||
if (successful && (rx_buff != NULL) && (rx_buff_length > 0)) {
|
||||
memcpy(rx_buff, (const uint8_t *)(i2c_master_buffer + read_index),
|
||||
sizeof(uint8_t) * rx_buff_length);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
puts(
|
||||
"[i2c.c/i2cRead]: the txBuff is not valid or has not a valid \
|
||||
length value !\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The interrupt handler for the I2C0 interface.
|
||||
* It deals only with the master mode.
|
||||
*
|
||||
*/
|
||||
void i2c_interface0_master_handler(void) //__irq
|
||||
{
|
||||
//puts("entering I2C handler function\n");
|
||||
uint8_t state_value;
|
||||
|
||||
/* this handler deals with master read and master write only */
|
||||
state_value = I20STAT;
|
||||
|
||||
//IENABLE; /* handles nested interrupt */
|
||||
//irq_enable();
|
||||
switch (state_value) {
|
||||
case 0x08: /* A Start condition is issued. */
|
||||
//puts("A Start condition is issued\n");
|
||||
I20DAT = i2c_master_buffer[0];
|
||||
//printf("I22DAT = %lu\n", I22DAT);
|
||||
I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
i2c_master_state = I2C_STARTED;
|
||||
break;
|
||||
|
||||
case 0x10: /* A repeated started is issued */
|
||||
//puts("A repeated Start is issued\n");
|
||||
// if ( I2CCmd == L3DG420_WHO_AM_I)
|
||||
// {
|
||||
// I22DAT = I2CMasterBuffer[2];
|
||||
// }
|
||||
I20DAT = i2c_master_buffer[2];
|
||||
I20CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
i2c_master_state = I2C_RESTARTED;
|
||||
break;
|
||||
|
||||
case 0x18: /* Regardless, it's a ACK */
|
||||
|
||||
//puts("got an Ack\n");
|
||||
if (i2c_master_state == I2C_STARTED) {
|
||||
I20DAT = i2c_master_buffer[1 + wr_index];
|
||||
wr_index++;
|
||||
i2c_master_state = DATA_ACK;
|
||||
|
||||
}
|
||||
|
||||
I20CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
|
||||
case 0x30:
|
||||
|
||||
//puts("Data byte has been transmitted\n");
|
||||
if (wr_index != i2c_write_length) {
|
||||
|
||||
// this should be the last one
|
||||
I20DAT = i2c_master_buffer[1 + wr_index];
|
||||
|
||||
if (wr_index != i2c_write_length) {
|
||||
i2c_master_state = DATA_ACK;
|
||||
}
|
||||
else {
|
||||
i2c_master_state = DATA_NACK;
|
||||
I20CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
|
||||
if (i2c_read_length != 0) {
|
||||
I20CONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
i2c_master_state = I2C_REPEATED_START;
|
||||
}
|
||||
}
|
||||
|
||||
wr_index++;
|
||||
}
|
||||
else {
|
||||
if (i2c_read_length != 0) {
|
||||
I20CONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
i2c_master_state = I2C_REPEATED_START;
|
||||
}
|
||||
else {
|
||||
i2c_master_state = DATA_NACK;
|
||||
I20CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
}
|
||||
}
|
||||
|
||||
I20CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x40: /* Master Receive, SLA_R has been sent */
|
||||
|
||||
//puts("Master Receive, SLA_R has been sent!\n");
|
||||
if (i2c_read_length >= 2) {
|
||||
I20CONSET = I2CONSET_AA; /* assert ACK after data is received */
|
||||
}
|
||||
|
||||
I20CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
// Data byte has been received, regardless following ACK or NACK
|
||||
case 0x50:
|
||||
case 0x58:
|
||||
//puts("Data received\n");
|
||||
i2c_master_buffer[3 + rd_index] = I20DAT;
|
||||
rd_index++;
|
||||
|
||||
if (rd_index < (i2c_read_length - 1)) {
|
||||
i2c_master_state = DATA_ACK;
|
||||
I20CONSET = I2CONSET_AA; /* assert ACK after data is received */
|
||||
}
|
||||
else {
|
||||
I20CONCLR = I2CONCLR_AAC; /* NACK after data is received */
|
||||
}
|
||||
|
||||
if (rd_index == i2c_read_length) {
|
||||
rd_index = 0;
|
||||
i2c_master_state = DATA_NACK;
|
||||
}
|
||||
|
||||
I20CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x20: /* regardless, it's a NACK */
|
||||
case 0x48:
|
||||
I20CONCLR = I2CONCLR_SIC;
|
||||
i2c_master_state = DATA_NACK;
|
||||
break;
|
||||
|
||||
case 0x38: /*
|
||||
* Arbitration lost, in this example, we don't
|
||||
* deal with multiple master situation
|
||||
**/
|
||||
|
||||
//puts("Arbritration lost!\n");
|
||||
default:
|
||||
I20CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
}
|
||||
|
||||
//IDISABLE;
|
||||
//irq_disable();
|
||||
//puts("leave I2C handler function\n");
|
||||
VICVectAddr = 0; /* Acknowledge Interrupt */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The interrupt handler for the I2C1 interface.
|
||||
* It deals only with the master mode.
|
||||
*
|
||||
*/
|
||||
void i2c_interface1_master_handler(void) //__irq
|
||||
{
|
||||
//puts("entering I2C handler function\n");
|
||||
uint8_t state_value;
|
||||
|
||||
/* this handler deals with master read and master write only */
|
||||
state_value = I21STAT;
|
||||
|
||||
//IENABLE; /* handles nested interrupt */
|
||||
//irq_enable();
|
||||
switch (state_value) {
|
||||
case 0x08: /* A Start condition is issued. */
|
||||
//puts("A Start condition is issued\n");
|
||||
I21DAT = i2c_master_buffer[0];
|
||||
//printf("I22DAT = %lu\n", I22DAT);
|
||||
I21CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
i2c_master_state = I2C_STARTED;
|
||||
break;
|
||||
|
||||
case 0x10: /* A repeated started is issued */
|
||||
//puts("A repeated Start is issued\n");
|
||||
// if ( I2CCmd == L3DG420_WHO_AM_I)
|
||||
// {
|
||||
// I22DAT = I2CMasterBuffer[2];
|
||||
// }
|
||||
I21DAT = i2c_master_buffer[2];
|
||||
I21CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
i2c_master_state = I2C_RESTARTED;
|
||||
break;
|
||||
|
||||
case 0x18: /* Regardless, it's a ACK */
|
||||
|
||||
//puts("got an Ack\n");
|
||||
if (i2c_master_state == I2C_STARTED) {
|
||||
I21DAT = i2c_master_buffer[1 + wr_index];
|
||||
wr_index++;
|
||||
i2c_master_state = DATA_ACK;
|
||||
|
||||
}
|
||||
|
||||
I21CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
|
||||
case 0x30:
|
||||
|
||||
//puts("Data byte has been transmitted\n");
|
||||
if (wr_index != i2c_write_length) {
|
||||
// this should be the last one
|
||||
I21DAT = i2c_master_buffer[1 + wr_index];
|
||||
|
||||
if (wr_index != i2c_write_length) {
|
||||
i2c_master_state = DATA_ACK;
|
||||
}
|
||||
else {
|
||||
i2c_master_state = DATA_NACK;
|
||||
I21CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
|
||||
if (i2c_read_length != 0) {
|
||||
I21CONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
i2c_master_state = I2C_REPEATED_START;
|
||||
}
|
||||
}
|
||||
|
||||
wr_index++;
|
||||
}
|
||||
else {
|
||||
if (i2c_read_length != 0) {
|
||||
I21CONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
i2c_master_state = I2C_REPEATED_START;
|
||||
}
|
||||
else {
|
||||
i2c_master_state = DATA_NACK;
|
||||
I21CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
}
|
||||
}
|
||||
|
||||
I21CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x40: /* Master Receive, SLA_R has been sent */
|
||||
|
||||
//puts("Master Receive, SLA_R has been sent!\n");
|
||||
if (i2c_read_length >= 2) {
|
||||
I21CONSET = I2CONSET_AA; /* assert ACK after data is received */
|
||||
}
|
||||
|
||||
I21CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x50: /*
|
||||
* Data byte has been received, regardless following ACK or
|
||||
* NACK
|
||||
**/
|
||||
case 0x58:
|
||||
//puts("Data received\n");
|
||||
i2c_master_buffer[3 + rd_index] = I21DAT;
|
||||
rd_index++;
|
||||
|
||||
if (rd_index < (i2c_read_length - 1)) {
|
||||
i2c_master_state = DATA_ACK;
|
||||
I21CONSET = I2CONSET_AA; /* assert ACK after data is received */
|
||||
}
|
||||
else {
|
||||
I21CONCLR = I2CONCLR_AAC; /* NACK after data is received */
|
||||
}
|
||||
|
||||
if (rd_index == i2c_read_length) {
|
||||
rd_index = 0;
|
||||
i2c_master_state = DATA_NACK;
|
||||
}
|
||||
|
||||
I21CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x20: /* regardless, it's a NACK */
|
||||
case 0x48:
|
||||
I21CONCLR = I2CONCLR_SIC;
|
||||
i2c_master_state = DATA_NACK;
|
||||
break;
|
||||
|
||||
case 0x38: /*
|
||||
* Arbitration lost, in this example, we don't
|
||||
* deal with multiple master situation
|
||||
**/
|
||||
|
||||
//puts("Arbritration lost!\n");
|
||||
default:
|
||||
I21CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
}
|
||||
|
||||
//IDISABLE;
|
||||
//irq_disable();
|
||||
//puts("leave I2C handler function\n");
|
||||
VICVectAddr = 0; /* Acknowledge Interrupt */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The interrupt handler for the I2C2 interface.
|
||||
* It deals only with the master mode.
|
||||
*
|
||||
*/
|
||||
void i2c_interface2_master_handler(void) //__irq
|
||||
{
|
||||
//puts("entering I2C handler function\n");
|
||||
uint8_t state_value;
|
||||
|
||||
/* this handler deals with master read and master write only */
|
||||
state_value = I22STAT;
|
||||
|
||||
//IENABLE; /* handles nested interrupt */
|
||||
//irq_enable();
|
||||
switch (state_value) {
|
||||
case 0x08: /* A Start condition is issued. */
|
||||
//puts("A Start condition is issued\n");
|
||||
I22DAT = i2c_master_buffer[0];
|
||||
//printf("I22DAT = %lu\n", I22DAT);
|
||||
I22CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
i2c_master_state = I2C_STARTED;
|
||||
break;
|
||||
|
||||
case 0x10: /* A repeated started is issued */
|
||||
//puts("A repeated Start is issued\n");
|
||||
// if ( I2CCmd == L3DG420_WHO_AM_I)
|
||||
// {
|
||||
// I22DAT = I2CMasterBuffer[2];
|
||||
// }
|
||||
I22DAT = i2c_master_buffer[2];
|
||||
I22CONCLR = (I2CONCLR_SIC | I2CONCLR_STAC);
|
||||
i2c_master_state = I2C_RESTARTED;
|
||||
break;
|
||||
|
||||
case 0x18: /* Regardless, it's a ACK */
|
||||
|
||||
//puts("got an Ack\n");
|
||||
if (i2c_master_state == I2C_STARTED) {
|
||||
I22DAT = i2c_master_buffer[1 + wr_index];
|
||||
wr_index++;
|
||||
i2c_master_state = DATA_ACK;
|
||||
|
||||
}
|
||||
|
||||
I22CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x28: /* Data byte has been transmitted, regardless ACK or NACK */
|
||||
case 0x30:
|
||||
|
||||
//puts("Data byte has been transmitted\n");
|
||||
if (wr_index != i2c_write_length) {
|
||||
// this should be the last one
|
||||
I22DAT = i2c_master_buffer[1 + wr_index];
|
||||
|
||||
if (wr_index != i2c_write_length) {
|
||||
i2c_master_state = DATA_ACK;
|
||||
}
|
||||
else {
|
||||
i2c_master_state = DATA_NACK;
|
||||
I22CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
|
||||
if (i2c_read_length != 0) {
|
||||
I22CONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
i2c_master_state = I2C_REPEATED_START;
|
||||
}
|
||||
}
|
||||
|
||||
wr_index++;
|
||||
}
|
||||
else {
|
||||
if (i2c_read_length != 0) {
|
||||
I22CONSET = I2CONSET_STA; /* Set Repeated-start flag */
|
||||
i2c_master_state = I2C_REPEATED_START;
|
||||
}
|
||||
else {
|
||||
i2c_master_state = DATA_NACK;
|
||||
I22CONSET = I2CONSET_STO; /* Set Stop flag */
|
||||
}
|
||||
}
|
||||
|
||||
I22CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x40: /* Master Receive, SLA_R has been sent */
|
||||
|
||||
//puts("Master Receive, SLA_R has been sent!\n");
|
||||
if (i2c_read_length >= 2) {
|
||||
I22CONSET = I2CONSET_AA; /* assert ACK after data is received */
|
||||
}
|
||||
|
||||
I22CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x50: /*
|
||||
* Data byte has been received, regardless following ACK or
|
||||
* NACK
|
||||
**/
|
||||
case 0x58:
|
||||
//puts("Data received\n");
|
||||
i2c_master_buffer[3 + rd_index] = I22DAT;
|
||||
rd_index++;
|
||||
|
||||
if (rd_index < (i2c_read_length - 1)) {
|
||||
i2c_master_state = DATA_ACK;
|
||||
I22CONSET = I2CONSET_AA; /* assert ACK after data is received */
|
||||
}
|
||||
else {
|
||||
I22CONCLR = I2CONCLR_AAC; /* NACK after data is received */
|
||||
}
|
||||
|
||||
if (rd_index == i2c_read_length) {
|
||||
rd_index = 0;
|
||||
i2c_master_state = DATA_NACK;
|
||||
}
|
||||
|
||||
I22CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
|
||||
case 0x20: /* regardless, it's a NACK */
|
||||
case 0x48:
|
||||
I22CONCLR = I2CONCLR_SIC;
|
||||
i2c_master_state = DATA_NACK;
|
||||
break;
|
||||
|
||||
case 0x38: /*
|
||||
* Arbitration lost, in this example, we don't
|
||||
* deal with multiple master situation
|
||||
**/
|
||||
|
||||
//puts("Arbritration lost!\n");
|
||||
default:
|
||||
I22CONCLR = I2CONCLR_SIC;
|
||||
break;
|
||||
}
|
||||
|
||||
//IDISABLE;
|
||||
//irq_disable();
|
||||
//puts("leave I2C handler function\n");
|
||||
VICVectAddr = 0; /* Acknowledge Interrupt */
|
||||
}
|
||||
|
||||
void i2c_set_slave_mode(uint8_t i2c_interface, uint8_t slave_addr)
|
||||
{
|
||||
switch (i2c_interface) {
|
||||
case I2C0:
|
||||
I20ADR = slave_addr;
|
||||
break;
|
||||
|
||||
case I2C1_0:
|
||||
case I2C1_1:
|
||||
I21ADR = slave_addr;
|
||||
break;
|
||||
|
||||
case I2C2:
|
||||
I22ADR = slave_addr;
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_enable_pull_up_resistor(uint8_t i2c_interface)
|
||||
{
|
||||
|
||||
switch (i2c_interface) {
|
||||
|
||||
case I2C1_0: // P0.0 SDA1, P0.1 SCL1
|
||||
puts("The on-chip pull-up resistor is enabled for the I2C1_0");
|
||||
PINMODE0 &= ~(BIT0 | BIT1 | BIT2 | BIT3);
|
||||
break;
|
||||
|
||||
case I2C1_1: // P0.19 SDA1, P0.20 SCL1
|
||||
puts("The on-chip pull-up resistor is enabled for the I2C1_1");
|
||||
PINMODE1 &= ~(BIT6 | BIT7 | BIT8 | BIT9);
|
||||
break;
|
||||
|
||||
case I2C2: // P0.10 SDA2, P0.11 SCL2
|
||||
puts("The on-chip pull-up resistor is enabled for the I2C2");
|
||||
PINMODE0 &= ~(BIT20 | BIT21 | BIT22 | BIT23);
|
||||
//PINMODE0 &= ~(BIT20 | BIT22);
|
||||
}
|
||||
}
|
||||
|
||||
void i2c_disable_pull_up_resistor(uint8_t i2c_interface)
|
||||
{
|
||||
switch (i2c_interface) {
|
||||
case I2C1_0: // P0.0 SDA1, P0.1 SCL1
|
||||
puts("The on-chip pull-up resistor is disbled for the I2C1_0");
|
||||
PINMODE0 &= ~(BIT0 | BIT2);
|
||||
PINMODE0 |= (BIT1 | BIT3);
|
||||
break;
|
||||
|
||||
case I2C1_1: // P0.19 SDA1, P0.20 SCL1
|
||||
puts("The on-chip pull-up resistor is disabled for the I2C1_1");
|
||||
PINMODE1 &= ~(BIT6 | BIT8);
|
||||
PINMODE1 |= (BIT7 | BIT9);
|
||||
break;
|
||||
|
||||
case I2C2: // P0.10 SDA2, P0.11 SCL2
|
||||
puts("The on-chip pull-up resistor is disbled for the I2C2");
|
||||
PINMODE0 &= ~(BIT20 | BIT22);
|
||||
PINMODE1 |= (BIT21 | BIT23);
|
||||
|
||||
}
|
||||
}
|
@ -1,337 +0,0 @@
|
||||
/*
|
||||
* i2c.h - Definitions for the I2C interface and the functions
|
||||
* for the LPC2387 chip.
|
||||
*
|
||||
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @internal
|
||||
* @brief The I2C interface driver definitions for the LPC2387 chip.
|
||||
* The driver is full abstracted supporting all the i2c-interfaces
|
||||
* of the LPC2387 chip. The user need only to give the requested
|
||||
* i2c-interface and the transmission baudrate. The user can
|
||||
* optionally give its own master interrupt handler. If the user
|
||||
* does not declare a handler, an appropriate interrupt is
|
||||
* automatically registered for the specific i2c-interface.
|
||||
*
|
||||
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
* @author Marco Ziegert <ziegert@inf.fu-berlin.de>
|
||||
* @author Benjamin Aschenbrenner
|
||||
* @version $Revision: 3857 $
|
||||
*
|
||||
* @note $Id: i2c.h 3857 2013-09-02 18:11:27 kasmi $
|
||||
*/
|
||||
|
||||
#ifndef I2C_H
|
||||
#define I2C_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define I2C_BUFSIZE 0x23
|
||||
#define MAX_TIMEOUT 0x00FFFFFF
|
||||
|
||||
#define I2CMASTER 0x01
|
||||
#define I2CSLAVE 0x02
|
||||
|
||||
//define slave addresses and data registers
|
||||
|
||||
#define RD_BIT 0x01
|
||||
#define AUTO_INC_BIT 0x80
|
||||
#define WRITE_ENABLE_BIT_MASK 0XFE
|
||||
#define READ_ENABLE_BIT_MASK 0x1
|
||||
|
||||
#define I2C_IDLE 0
|
||||
#define I2C_STARTED 1
|
||||
#define I2C_RESTARTED 2
|
||||
#define I2C_REPEATED_START 3
|
||||
#define DATA_ACK 4
|
||||
#define DATA_NACK 5
|
||||
|
||||
#define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */
|
||||
#define I2CONSET_AA 0x00000004
|
||||
#define I2CONSET_SI 0x00000008
|
||||
#define I2CONSET_STO 0x00000010
|
||||
#define I2CONSET_STA 0x00000020
|
||||
|
||||
#define I2CONCLR_AAC 0x00000004 /* I2C Control clear Register */
|
||||
#define I2CONCLR_SIC 0x00000008
|
||||
#define I2CONCLR_STAC 0x00000020
|
||||
#define I2CONCLR_I2ENC 0x00000040
|
||||
|
||||
#define I2DAT_I2C 0x00000000 /* I2C Data Reg */
|
||||
#define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */
|
||||
#define I2SCLH_SCLH 45 /* I2C SCL Duty Cycle High Reg */
|
||||
#define I2SCLL_SCLL 45 /* I2C SCL Duty Cycle Low Reg */
|
||||
|
||||
//I2C interfaces
|
||||
#define I2C0 0 // P0.27 SDA0, P0.28 SCL0
|
||||
#define I2C1_0 1 // P0.0 SDA1, P0.1 SCL1
|
||||
#define I2C1_1 2 // P0.19 SDA1, P0.20 SCL1
|
||||
#define I2C2 3 // P0.10 SDA2, P0.11 SCL2
|
||||
|
||||
|
||||
/* Functions definitions */
|
||||
|
||||
/**
|
||||
* @brief Initialize the I2C-Interface with the appropriate operation
|
||||
* mode, baud rate and other parameter.
|
||||
* The user can optionally give a master interrupt handler. If the
|
||||
* user does not declare a handler, an appropriate interrupt is
|
||||
* automatically registered for the specific i2c interface.
|
||||
*
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] i2c_mode the operating mode.
|
||||
* @param[in] slave_addr the slave address.
|
||||
* @param[in] baud_rate the baud rate.
|
||||
* @param[in] handler the I2C2 Interrupt handler (optional); by giving
|
||||
* a NULL as parameter, an appropriate interrupt is
|
||||
* automatically selected.
|
||||
*
|
||||
* @return true if the I2C interrupt handler was installed correctly, otherwise
|
||||
* false.
|
||||
*/
|
||||
bool i2c_initialize(uint8_t i2c_interface, uint32_t i2c_mode,
|
||||
uint8_t slave_addr, uint32_t baud_rate, void *handler);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read from an appropriate slave device over the I2C-Interface.
|
||||
* The read values are stored in a buffer, which it is handed to
|
||||
* the function.
|
||||
*
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] slave_addr the slave address
|
||||
* @param[in] reg_addr a register address, which is residing in the
|
||||
* slave device.
|
||||
* @param[out] rx_buff a pointer to a receive buffer.
|
||||
* @param[in] rx_buff_length the number of receiving bytes resp.
|
||||
* the receive-buffer length.
|
||||
*
|
||||
* @return true if the read transaction is successfully completed, otherwise
|
||||
* false.
|
||||
*/
|
||||
bool i2c_read(uint8_t i2c_interface, uint8_t slave_addr, uint8_t reg_addr,
|
||||
uint8_t *rx_buff, uint8_t rx_buff_length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Write to an appropriate slave device over the I2C-Interface.
|
||||
* The values are stored in a buffer, which it is handed to the
|
||||
* function.
|
||||
*
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] slave_addr the slave address
|
||||
* @param[in] reg_addr a register address, which is residing in the
|
||||
* slave device.
|
||||
* @param[in] tx_buff pointer to a transmitting buffer.
|
||||
* @param[in] tx_buff_length the number of transmitting bytes resp.
|
||||
* the transmit-buffer length.
|
||||
*
|
||||
* @return true if the write transaction is successfully completed, otherwise
|
||||
* false.
|
||||
*/
|
||||
bool i2c_write(uint8_t i2c_interface, uint8_t slave_addr, uint8_t reg_addr,
|
||||
uint8_t *tx_buff, uint8_t tx_buff_length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Simultaneous sending and receiving to/from the I2C-Interface.
|
||||
* The sending/receiving bytes are stored in two buffers, which are
|
||||
* handed to the function.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] slave_addr slave address
|
||||
* @param[in] tx_buff pointer to a sending buffer.
|
||||
* @param[in] tx_buff_length the number of sending bytes resp.
|
||||
* the send-buffer length.
|
||||
* @param[out] rx_buff pointer to a receive buffer.
|
||||
* @param[in] rx_buff_length the number of receiving bytes resp.
|
||||
* the receive-buffer length.
|
||||
*
|
||||
* @return true if the write/receive transaction are successfully completed,
|
||||
* otherwise false.
|
||||
*/
|
||||
bool i2c_trans_receive(uint8_t i2c_interface, uint8_t slave_addr,
|
||||
uint8_t *tx_buff, uint8_t tx_buff_length,
|
||||
uint8_t *rx_buff, uint8_t rx_buff_length);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the appropriate I2C interface.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
*/
|
||||
void i2c_active_power(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Select the appropriate pins for the I2C interface.
|
||||
* It selects the respective Serial Data Line (SDAx) and Serial
|
||||
* Clock (SCLx).
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
*/
|
||||
void i2c_pin_select(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear the I2C control register.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
*/
|
||||
void i2c_clear_control_register(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the I2C baud rate.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] baud_rate the baud rate.
|
||||
*
|
||||
*/
|
||||
void i2c_set_baud_rate(uint8_t i2c_interface, uint32_t baud_rate);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register an interrupt handler for the I2C interface.
|
||||
* The user can register his own irq-handler.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] handler the i2c irq-handler.
|
||||
*
|
||||
* @return true if the the interrupt handler is successfully registered,
|
||||
* otherwise false.
|
||||
*
|
||||
*/
|
||||
bool i2c_irq_handler_register(uint8_t i2c_interface, void *handler);
|
||||
|
||||
|
||||
/**
|
||||
* @brief This routine complete a I2C transaction from start to stop
|
||||
* conditions.
|
||||
* All the intermitten steps are handled in the interrupt handler.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
* @return false if the start condition can never be generated and timed out,
|
||||
* otherwise true.
|
||||
*
|
||||
*/
|
||||
bool i2c_transaction(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable master transmitter mode for the appropriate
|
||||
* i2c-interface.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
*/
|
||||
void i2c_initial_master_transmitter_mode(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set slave mode for the appropriate i2c-interface.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] slave_addr the slave address.
|
||||
*
|
||||
*/
|
||||
void i2c_set_slave_mode(uint8_t i2c_interface, uint8_t slave_addr);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clear a number of bytes in a buffer.
|
||||
*
|
||||
* @param[in] ptr pointer to a buffer
|
||||
* @param[in] size the number of bytes, that must be cleared.
|
||||
*
|
||||
*/
|
||||
void i2c_clear_buffer(void *ptr, uint32_t size);
|
||||
|
||||
/**
|
||||
* @brief Create a I2C start condition.
|
||||
*
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
* @return false if the start condition is timed out, otherwise true.
|
||||
*
|
||||
*/
|
||||
bool i2c_start(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set a I2C stop condition.
|
||||
* If the function never exit, it's a fatal bus error
|
||||
*
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces can be
|
||||
* selected: i2c0, i2c1 and i2c2.
|
||||
*
|
||||
* @return true if the stop condition is issued, otherwise it never returns.
|
||||
*
|
||||
*/
|
||||
bool i2c_stop(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Enable the on-chip pull-up resistor for the appropriate
|
||||
* i2c-interface.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, only the i2c1 and the
|
||||
* i2c2-interfaces are supported. The pin mode
|
||||
* cannot be selected for pins P0[27] to P0[31].
|
||||
* Pins P0[27] and P0[28] are dedicated I2C
|
||||
* open-drain pins without pull-up/down.
|
||||
*/
|
||||
void i2c_enable_pull_up_resistor(uint8_t i2c_interface);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Disable the on-chip pull-up resistor for the appropriate
|
||||
* i2c-interface.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, only the i2c1 and the
|
||||
* i2c2-interfaces are supported. The pin mode
|
||||
* cannot be selected for pins P0[27] to P0[31].
|
||||
* Pins P0[27] and P0[28] are dedicated I2C
|
||||
* open-drain pins without pull-up/down.
|
||||
*/
|
||||
void i2c_disable_pull_up_resistor(uint8_t i2c_interface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* I2C_H */
|
@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup drivers_lm75a LM75A
|
||||
* @ingroup drivers_sensors
|
||||
* @brief Driver for the LM75A digital temperature sensor and thermal watchdog
|
||||
*
|
||||
* The connection between the MCU and the LM75A is based on the i2c-interface.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @internal
|
||||
* @brief Definitions of the LM75A temperature sensor driver.
|
||||
*
|
||||
* The connection between the LM75A and the MCU is based on the I2C-interface.
|
||||
*
|
||||
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef LM75A_H
|
||||
#define LM75A_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include "i2c.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name LM75A register addresses
|
||||
* @{
|
||||
*/
|
||||
#define LM75A_ADDR 0x48
|
||||
#define LM75A_TEMPERATURE_REG 0x0
|
||||
#define LM75A_CONFIG_REG 0x1
|
||||
#define LM75A_THYST_REG 0x2
|
||||
#define LM75A_OVER_TEMP_REG 0x3
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Define the used I2C Interface
|
||||
*/
|
||||
//#define LM75A_I2C_INTERFACE I2C0 // P0.27 SDA0, P0.28 SCL0
|
||||
#define LM75A_I2C_INTERFACE I2C1_0 // P0.0 SDA1, P0.1 SCL1
|
||||
//#define LM75A_I2C_INTERFACE I2C1_1 // P0.19 SDA1, P0.20 SCL1
|
||||
//#define LM75A_I2C_INTERFACE I2C2 // P0.10 SDA2, P0.11 SCL2
|
||||
|
||||
/**
|
||||
* @brief LM75A operation modes
|
||||
*/
|
||||
enum OPERATION_MODES {
|
||||
LM75A_NORMAL_OPERATION_MODE,
|
||||
LM75A_SHUTDOWN_MODE,
|
||||
LM75A_COMPARATOR_MODE,
|
||||
LM75A_INTERRUPT_MODE
|
||||
};
|
||||
|
||||
/**
|
||||
* @name Common definitions for LMA75A
|
||||
* @{
|
||||
*/
|
||||
#define LM75A_BIT0 0x0
|
||||
#define LM75A_BIT1 0x1
|
||||
#define LM75A_BIT2 0x2
|
||||
#define LM75A_BIT3 0x3
|
||||
#define LM75A_BIT4 0x4
|
||||
#define LM75A_BIT5 0x5
|
||||
#define LM75A_BIT6 0x6
|
||||
#define LM75A_BIT7 0x7
|
||||
#define LM75A_BIT8 0x8
|
||||
#define LM75A_BIT9 0x9
|
||||
#define LM75A_BIT10 0xA
|
||||
#define LM75A_BIT15 0xF
|
||||
#define LM75A_MOST_SIG_BYTE_MASK 0xFF00
|
||||
#define LM75A_LEAST_SIG_BYTE_MASK 0x00FF
|
||||
#define LM75A_DATA_BITS_MASK 0x07FF
|
||||
#define LM75A_SIGN_BIT_MASK (1<<LM75A_BIT10)
|
||||
#define LM75A_LSB_MASK 0x1
|
||||
#define LM75A_EXTINT_MODE 0x1
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name LM75A configuration register
|
||||
* @{
|
||||
*/
|
||||
#define LM75A_ACTIVE_LOW 0
|
||||
#define LM75A_ACTIVE_HIGH 1
|
||||
#define LM75A_DEFAULT_CONFIG_VALUE 0
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief LM75A default values
|
||||
*/
|
||||
enum DEFAULT_VALUES {
|
||||
LM75A_DEFAULT_TOS = 80,
|
||||
LM75A_DEFAULT_THYST = 75,
|
||||
LM75A_DEFAULT_OPERATION = LM75A_NORMAL_OPERATION_MODE,
|
||||
LM75A_DEFAULT_MODE = LM75A_COMPARATOR_MODE,
|
||||
LM75A_DEFAULT_POLARITY = LM75A_ACTIVE_LOW,
|
||||
LM75A_DEFAULT_FAULT_NUM = 1
|
||||
};
|
||||
|
||||
/**
|
||||
* @name define inter-threads messages
|
||||
* @{
|
||||
*/
|
||||
#define LM75A_EXIT_MSG 0
|
||||
#define LM75A_SAMPLING_MSG 1
|
||||
#define LM75A_SLEEP_MSG 2
|
||||
#define LM75A_WEAKUP_MSG 3
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Set the over-temperature shutdown threshold (TOS).
|
||||
*
|
||||
* @param[in] tos the TOS value.
|
||||
*
|
||||
*/
|
||||
void lm75A_set_over_temperature(float_t tos);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the hysteresis temperature.
|
||||
*
|
||||
* @param[in] thsyt the hysteresis value.
|
||||
*
|
||||
*/
|
||||
void lm75A_set_hysteresis_temperature(float_t thsyt);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set various operation modes of the temperature sensor.
|
||||
* The LM75A provide four modes: normal, comparator, interrupt,
|
||||
* and the shutdown mode.
|
||||
* All these modes are defined in the lm75a-temp-sensor.h
|
||||
*
|
||||
* @param[in] op_mode the operation mode value: the normal, shutdown,
|
||||
* comparator, or interrupt mode.
|
||||
*
|
||||
*/
|
||||
void lm75A_set_operation_mode(uint8_t op_mode);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the content of the configuration register.
|
||||
*
|
||||
* @return the configuration register value.
|
||||
*
|
||||
*/
|
||||
uint8_t lm75A_get_config_reg(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the adjusted hysteresis temperature.
|
||||
*
|
||||
* @return the content of the hysteresis register.
|
||||
*
|
||||
*/
|
||||
float_t lm75A_get_hysteresis_temperature(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the adjusted over-temperature shutdown threshold (TOS).
|
||||
*
|
||||
* @return the content of the TOS-register.
|
||||
*
|
||||
*/
|
||||
float_t lm75A_get_over_temperature(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the ambient temperature which is measured from the
|
||||
* LM75A sensor.
|
||||
*
|
||||
* @return the content of the temperature register.
|
||||
*
|
||||
*/
|
||||
float_t lm75A_get_ambient_temperature(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Set the LM75A sensor in the initial state.
|
||||
* The temperature sensor has the following values in this state:
|
||||
* config_register = 0; hyst_register = 75; the tos_reg = 80.
|
||||
*
|
||||
*/
|
||||
void lm75A_reset(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start a continuous sampling of the temperature values.
|
||||
* This function prints the values of all registers over
|
||||
* the rs232 interface.
|
||||
*
|
||||
* @param[in] extern_interrupt_task pointer to an external task handler that
|
||||
* is executed, if an external interrupt
|
||||
* occurrs left. This is an optional
|
||||
* parameter therefore NULL is a legal value.
|
||||
*/
|
||||
void lm75A_start_sensor_sampling(void (*extern_interrupt_task)(void));
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register an interrupt handler for the external interrupt.
|
||||
* Only the port0 and port2 are supported.
|
||||
*
|
||||
* @param[in] port port number.
|
||||
* @param[in] pin_bit_mask pin number in form of a bit mask: Pin0 --> BIT0,
|
||||
* Pin1 --> BIT1, Pin2 --> BIT2 = 2^2 = 4
|
||||
* @param[in] flags define if the interrupt is generated on rising
|
||||
* or falling edge (#GPIOINT_RISING_EDGE,
|
||||
* #GPIOINT_FALLING_EDGE).
|
||||
* @param[in] handler pointer to an interrupt handler.
|
||||
*
|
||||
* @return true if the the external interrupt handler is successfully
|
||||
* registered, otherwise false.
|
||||
*/
|
||||
bool lm75A_ext_irq_handler_register(int32_t port, uint32_t pin_bit_mask,
|
||||
int32_t flags, void *handler);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize the LM75A temperature sensor.
|
||||
* The baud rate and the handler for the external interrupt can be
|
||||
* initialized. The external interrupt handler is optional, if no
|
||||
* handler is available, the NULL-value can be entered.
|
||||
* The hysteresis and the over-temperature are displayed before and
|
||||
* after a rest action is performed. After this the LM7A sensor is
|
||||
* set in the interrupt or the comparator mode.
|
||||
*
|
||||
* @param[in] i2c_interface the i2c interface, several interfaces
|
||||
* can be selected: i2c0, i2c1 and i2c2.
|
||||
* @param[in] baud_rate the baud rate.
|
||||
* @param[in] external_interr_handler pointer to a handler for the external
|
||||
* interrupt.
|
||||
*
|
||||
* @return true if the I2C interface and the external interrupt handler are
|
||||
* successfully initialized, otherwise false.
|
||||
*/
|
||||
bool lm75A_init(uint8_t i2c_interface, uint32_t baud_rate,
|
||||
void *external_interr_handler);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Register the external interrupt handler for the over-temperature
|
||||
* shutdown output.
|
||||
*
|
||||
* @param[in] handler pointer to a handler for the external interrupts.
|
||||
*
|
||||
* @return true if the the external interrupt handler is successfully
|
||||
* registered, otherwise false.
|
||||
*/
|
||||
bool lm75A_external_interrupt_register(void *handler);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Alarm the sensor sampling task about an external interrupt.
|
||||
*
|
||||
* @param[in] b is true if an external interrupt is occurred, otherwise false.
|
||||
*
|
||||
*/
|
||||
void lm75A_set_in_alarm(bool b);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
#endif /* LM75A_H */
|
@ -1 +0,0 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -1,311 +0,0 @@
|
||||
/*
|
||||
* lm75a-temp-sensor.c - Driver for the LM75A temperature sensor based on the
|
||||
* i2c interface.
|
||||
*
|
||||
* Copyright (C) 2013 Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @internal
|
||||
* @brief Driver for the LM75A temperature sensor.
|
||||
* The communication between the LM75A and the MCU is
|
||||
* based on the i2c interface.
|
||||
*
|
||||
* @author Zakaria Kasmi <zkasmi@inf.fu-berlin.de>
|
||||
* @version $Revision: 3855 $
|
||||
*
|
||||
* @note $Id: lm75a-temp-sensor.c 3855 2013-09-05 13:53:49 kasmi $
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "msg.h"
|
||||
#include "thread.h"
|
||||
#include "lpc2387.h"
|
||||
#include "gpioint.h"
|
||||
#include "i2c.h"
|
||||
#include "lm75a-temp-sensor.h"
|
||||
#include "board.h"
|
||||
#include "xtimer.h"
|
||||
|
||||
//declaration as volatile is important, otherwise no interrupt is triggered.
|
||||
volatile bool my_alarm = false;
|
||||
|
||||
static uint16_t get_2s_complement(uint16_t num)
|
||||
{
|
||||
return ~(num) + 1;
|
||||
}
|
||||
|
||||
//Write: MC --> Sensor
|
||||
static void to_bytes(float_t f, uint8_t *buff)
|
||||
{
|
||||
int32_t i = (int32_t)(f * 2);
|
||||
buff[0] = (uint8_t)((i >> LM75A_BIT1) & 0xFF);//Most signif. byte
|
||||
buff[1] = (uint8_t)((i & LM75A_BIT1) << LM75A_BIT7);//Least signif. byte
|
||||
}
|
||||
|
||||
static uint16_t to_uint16(uint8_t *buff)
|
||||
{
|
||||
if (buff != NULL) {
|
||||
return (buff[0] << LM75A_BIT8) | buff[1];
|
||||
}
|
||||
else {
|
||||
return UINT16_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
//Read: Sensor --> MC
|
||||
volatile static float_t to_float(uint8_t reg_addr, uint16_t reg_value)
|
||||
{
|
||||
uint16_t sign = reg_value & LM75A_SIGN_BIT_MASK;
|
||||
float_t f_temp = 0.0;
|
||||
float_t factor = 0.0;
|
||||
|
||||
switch (reg_addr) {
|
||||
case LM75A_OVER_TEMP_REG:
|
||||
case LM75A_THYST_REG:
|
||||
factor = 0.5;
|
||||
break;
|
||||
|
||||
case LM75A_TEMPERATURE_REG:
|
||||
factor = 0.125;
|
||||
}
|
||||
|
||||
if (sign) { //the number is negative
|
||||
f_temp = (get_2s_complement(reg_value) & LM75A_DATA_BITS_MASK)
|
||||
* -factor;
|
||||
}
|
||||
else { //the number is positive
|
||||
f_temp = reg_value * factor;
|
||||
}
|
||||
return f_temp;
|
||||
}
|
||||
|
||||
static void set_register(uint8_t i2c_interface, uint8_t reg_addr, float_t value)
|
||||
{
|
||||
bool status = false;
|
||||
uint8_t tx_buff[2];
|
||||
|
||||
switch (reg_addr) {
|
||||
case LM75A_OVER_TEMP_REG:
|
||||
case LM75A_THYST_REG:
|
||||
to_bytes(value, tx_buff);
|
||||
status = i2c_write(i2c_interface, LM75A_ADDR, reg_addr, tx_buff, 2);
|
||||
break;
|
||||
|
||||
case LM75A_CONFIG_REG:
|
||||
tx_buff[0] = (uint8_t) value;
|
||||
status = i2c_write(i2c_interface, LM75A_ADDR, reg_addr, tx_buff, 1);
|
||||
}
|
||||
|
||||
if (!status) {
|
||||
puts(
|
||||
"[lm75a_tempSensorI2C/lm75A_setRegister]: Slave is not ready !!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void lm75A_set_over_temperature(float_t tos)
|
||||
{
|
||||
set_register(LM75A_I2C_INTERFACE, LM75A_OVER_TEMP_REG, tos);
|
||||
}
|
||||
|
||||
void lm75A_set_hysteresis_temperature(float_t thsyt)
|
||||
{
|
||||
set_register(LM75A_I2C_INTERFACE, LM75A_THYST_REG, thsyt);
|
||||
}
|
||||
|
||||
static uint16_t lm75A_get_register_value(uint8_t i2c_interface,
|
||||
uint8_t reg_addr,
|
||||
uint8_t reg_size)
|
||||
{
|
||||
uint8_t rx_buff[reg_size];
|
||||
|
||||
i2c_clear_buffer(rx_buff, sizeof(rx_buff));
|
||||
if ((reg_size > 0) && (reg_size < 3)) {
|
||||
bool status = i2c_read(i2c_interface, LM75A_ADDR, reg_addr, rx_buff, sizeof(rx_buff));
|
||||
if (!status) { //Slave is not ready
|
||||
puts(
|
||||
"[lm75a_tempSensorI2C/lm75A_getConfigReg]: Slave is not\
|
||||
ready !\n");
|
||||
|
||||
if (reg_size < 2) {
|
||||
return UCHAR_MAX;
|
||||
}
|
||||
else {
|
||||
return UINT16_MAX;
|
||||
}
|
||||
}
|
||||
else { //Slave acknowledged
|
||||
if (reg_size < 2) {
|
||||
return rx_buff[0];
|
||||
}
|
||||
else {
|
||||
return to_uint16(rx_buff);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
puts("the register size must be less than 2");
|
||||
return UINT16_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t lm75A_get_config_reg(void)
|
||||
{
|
||||
return lm75A_get_register_value(LM75A_I2C_INTERFACE, LM75A_CONFIG_REG, 1);
|
||||
}
|
||||
|
||||
float_t lm75A_get_hysteresis_temperature(void)
|
||||
{
|
||||
uint16_t hyst_reg_value = 0;
|
||||
hyst_reg_value = lm75A_get_register_value(LM75A_I2C_INTERFACE,
|
||||
LM75A_THYST_REG, 2);
|
||||
hyst_reg_value = (hyst_reg_value >> LM75A_BIT7);
|
||||
return to_float(LM75A_THYST_REG, hyst_reg_value);
|
||||
}
|
||||
|
||||
float_t lm75A_get_over_temperature(void)
|
||||
{
|
||||
uint16_t over_temp = 0;
|
||||
|
||||
over_temp = lm75A_get_register_value(LM75A_I2C_INTERFACE,
|
||||
LM75A_OVER_TEMP_REG, 2);
|
||||
over_temp = (over_temp >> LM75A_BIT7);
|
||||
return to_float(LM75A_OVER_TEMP_REG, over_temp);
|
||||
}
|
||||
|
||||
float_t lm75A_get_ambient_temperature(void)
|
||||
{
|
||||
uint16_t amb_temp = 0;
|
||||
amb_temp = lm75A_get_register_value(LM75A_I2C_INTERFACE,
|
||||
LM75A_TEMPERATURE_REG, 2);
|
||||
amb_temp = (amb_temp >> LM75A_BIT5);
|
||||
return to_float(LM75A_TEMPERATURE_REG, amb_temp);
|
||||
}
|
||||
|
||||
void lm75A_reset(void)
|
||||
{
|
||||
lm75A_set_over_temperature(LM75A_DEFAULT_TOS);
|
||||
lm75A_set_hysteresis_temperature(LM75A_DEFAULT_THYST);
|
||||
set_register(LM75A_I2C_INTERFACE, LM75A_CONFIG_REG,
|
||||
LM75A_DEFAULT_CONFIG_VALUE);
|
||||
}
|
||||
|
||||
void lm75A_set_operation_mode(uint8_t op_mode)
|
||||
{
|
||||
uint8_t config_reg = lm75A_get_config_reg();
|
||||
|
||||
switch (op_mode) {
|
||||
case LM75A_NORMAL_OPERATION_MODE:
|
||||
config_reg &= ~(1 << LM75A_BIT0);
|
||||
break;
|
||||
|
||||
case LM75A_SHUTDOWN_MODE:
|
||||
config_reg |= (1 << LM75A_BIT0);
|
||||
break;
|
||||
|
||||
case LM75A_COMPARATOR_MODE:
|
||||
config_reg &= ~(1 << LM75A_BIT1);
|
||||
break;
|
||||
|
||||
case LM75A_INTERRUPT_MODE:
|
||||
config_reg |= (1 << LM75A_BIT1);
|
||||
break;
|
||||
|
||||
default:
|
||||
config_reg &= ~(1 << LM75A_BIT0);
|
||||
}
|
||||
set_register(LM75A_I2C_INTERFACE, LM75A_CONFIG_REG, config_reg);
|
||||
}
|
||||
|
||||
bool lm75A_ext_irq_handler_register(int32_t port, uint32_t pin_bit_mask,
|
||||
int32_t flags, void *handler)
|
||||
{
|
||||
return gpioint_set(port, pin_bit_mask, flags, handler);
|
||||
}
|
||||
|
||||
bool lm75A_init(uint8_t i2c_interface, uint32_t baud_rate,
|
||||
void *external_interr_handler)
|
||||
{
|
||||
if (i2c_initialize(i2c_interface, (uint32_t) I2CMASTER, 0, baud_rate, NULL)
|
||||
== false) { /* initialize I2C */
|
||||
puts("fatal error happened in i2c_initialize()\n");
|
||||
return false;
|
||||
}
|
||||
//i2c_enable_pull_up_resistor(i2c_interface);
|
||||
i2c_disable_pull_up_resistor(i2c_interface);
|
||||
|
||||
if ((external_interr_handler != NULL)
|
||||
&& lm75A_ext_irq_handler_register(2, BIT3, GPIOINT_FALLING_EDGE,
|
||||
external_interr_handler)) {
|
||||
printf("# %-70s%10s\n", "External interrupt handler registration",
|
||||
"...[OK]");
|
||||
}
|
||||
else {
|
||||
printf("# %-70s%10s\n", "External interrupt handler registration",
|
||||
"...[FAILED]");
|
||||
return false;
|
||||
}
|
||||
|
||||
puts("################## Before reset ##################");
|
||||
printf("configReg = %u\n", lm75A_get_config_reg());
|
||||
printf("hystTemp = %f\n", lm75A_get_hysteresis_temperature());
|
||||
printf("overTemp = %f\n", lm75A_get_over_temperature());
|
||||
lm75A_reset();
|
||||
|
||||
puts("\n################## After reset ##################");
|
||||
printf("configRegInitial = %u\n", lm75A_get_config_reg());
|
||||
printf("initialHystTemp = %f\n", lm75A_get_hysteresis_temperature());
|
||||
printf("initialOverTemp = %f\n", lm75A_get_over_temperature());
|
||||
|
||||
puts("\n################## New configuration ##################");
|
||||
// set the hysteresis temperature
|
||||
lm75A_set_hysteresis_temperature(32.0);
|
||||
printf("hystTemp = %f\n", lm75A_get_hysteresis_temperature());
|
||||
lm75A_set_over_temperature(33.0);
|
||||
printf("overTemp = %f\n", lm75A_get_over_temperature());
|
||||
|
||||
puts("\n################## Go to comparator mode ##################");
|
||||
lm75A_set_operation_mode(LM75A_COMPARATOR_MODE);
|
||||
printf("configReg = %u\n", lm75A_get_config_reg());
|
||||
// puts("\n################## Go to interrupt mode ##################");
|
||||
// lm75A_set_operation_mode(LM75A_INTERRUPT_MODE);
|
||||
// printf("configReg = %u\n", lm75A_get_config_reg());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void lm75A_set_in_alarm(bool b)
|
||||
{
|
||||
my_alarm = b;
|
||||
}
|
||||
|
||||
/*
|
||||
* Application entry point.
|
||||
*/
|
||||
void lm75A_start_sensor_sampling(void (*handler)(void))
|
||||
{
|
||||
/*
|
||||
* Normal main() thread activity.
|
||||
*/
|
||||
while (true) {
|
||||
printf("amb_temp = %3.3f\n", lm75A_get_ambient_temperature());
|
||||
|
||||
if (my_alarm && (handler != NULL)) {
|
||||
handler();
|
||||
my_alarm = false;
|
||||
}
|
||||
xtimer_usleep(100000);
|
||||
xtimer_usleep(100000);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user