diff --git a/examples/eeprom-test/Makefile b/examples/eeprom-test/Makefile index 0d78a7341..46c909138 100644 --- a/examples/eeprom-test/Makefile +++ b/examples/eeprom-test/Makefile @@ -1,5 +1,6 @@ CONTIKI_PROJECT = eeprom-test all: $(CONTIKI_PROJECT) +TARGET=mbxxx CONTIKI = ../.. include $(CONTIKI)/Makefile.include diff --git a/examples/eeprom-test/eeprom-test.c b/examples/eeprom-test/eeprom-test.c index c20e5d009..b5883eff5 100644 --- a/examples/eeprom-test/eeprom-test.c +++ b/examples/eeprom-test/eeprom-test.c @@ -43,56 +43,114 @@ #include /* For printf() */ +void +print_content() +{ + eeprom_addr_t addr_row = 0, j; + uint8_t i; + uint8_t byte; + + printf("\t"); + for(i = 0; i < 16; i++) + printf("0x%x\t", i); + printf + ("\n-----------------------------------------------------------------------------------------------------------------------------------------\n"); + + for(addr_row = 0; addr_row < EEPROM_SIZE / 16; ++addr_row) { + printf("0x%x\t|", addr_row * 16); + + for(j = 0; j < 16; j++) { + eeprom_read(addr_row * 16 + j, &byte, 1); + printf("0x%x\t", byte); + } + printf("\n"); + } +} + +void +erase_content() +{ + static eeprom_addr_t addr = 0; + + for(addr = 0; addr < EEPROM_SIZE; ++addr) { + eeprom_write(addr, 0, 1); + } +} + /*---------------------------------------------------------------------------*/ PROCESS(eeprom_test_process, "EEPROM Test Process"); AUTOSTART_PROCESSES(&eeprom_test_process); /*---------------------------------------------------------------------------*/ PROCESS_THREAD(eeprom_test_process, ev, data) { - static uint8_t counter = 0; - + static uint8_t counter = 0, error = 0; static eeprom_addr_t addr = 0; + uint8_t byte; + + uint8_t buffer[] = + { 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xBB, + 0xBB, 0xBB, 0xAA, 0xAA, 0xAA, 0xFF, 0xAA, 0xAA, 0xAA, 0xBB, + 0xBB, 0xBB, 0xCC, 0xCC, 0xCC, 0xBB, 0xBB, 0xBB, 0xAA, 0xAA, + 0xAA, 0xFF, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC, + 0xCC, 0xBB, 0xBB, 0xBB, 0xAA, 0xAA, 0xAA, 0xFF + }; PROCESS_BEGIN(); printf("eeprom-test: Size = %d bytes\n", EEPROM_SIZE); - /* Check to see if the EEPROM is empty */ - for(addr = 0; addr < EEPROM_SIZE; ++addr) { - uint8_t byte; + print_content(); + printf("\nErase EEPROM content\n"); + erase_content(); + + print_content(); + + counter = 0; + for(addr = 0; addr < EEPROM_SIZE; ++addr) { + eeprom_write(addr, &counter, 1); + counter += 1; + } + + counter = 0; + for(addr = 0; addr < EEPROM_SIZE; ++addr) { + byte = 0; eeprom_read(addr, &byte, 1); - if(byte != 0xFF) { + if(byte != counter) { + error++; + eeprom_read(addr, &byte, 1); + printf + ("eeprom-test: EEPROM write failure! 0x%x =/= 0x%x at address 0x%x\n", + byte, counter, addr); break; } + counter += 1; } - if(addr == EEPROM_SIZE) { - printf("eeprom-test: EEPROM is empty. Proceding with write test...\n"); - - counter = 0; - for(addr = 0; addr < EEPROM_SIZE; ++addr) { - eeprom_write(addr, &counter, 1); - counter += 1; - } - - counter = 0; - for(addr = 0; addr < EEPROM_SIZE; ++addr) { - uint8_t byte; - - eeprom_read(addr, &byte, 1); - if(byte != counter) { - printf("eeprom-test: EEPROM write failure!\n"); - break; - } - counter += 1; - } - + if(error) + printf("eeprom-test: EEPROM write test FAIL!\n%d errors", error); + else printf("eeprom-test: EEPROM write test success!\n"); - } else { - printf("eeprom-test: EEPROM is NOT empty! Skipping write test.\n"); - } + + print_content(); + + printf("Fill memory with buffer\n"); + + for(addr = 0; addr < EEPROM_SIZE; addr += sizeof(buffer)) { + eeprom_write(addr, ((unsigned char *)buffer), sizeof(buffer)); + } +/* + printf("Write data buffer %d at address 0x0\n", sizeof(buffer)); + eeprom_write(0x0, ((unsigned char *)buffer), sizeof(buffer)); + + printf("Write data buffer %d at address 0x40\n", sizeof(buffer)); + eeprom_write(0x40, ((unsigned char *)buffer), sizeof(buffer)); + + printf("Write data buffer %d at address 0x95\n", sizeof(buffer)); + eeprom_write(0x95, ((unsigned char *)buffer), sizeof(buffer)); +*/ + print_content(); PROCESS_END(); } /*---------------------------------------------------------------------------*/ diff --git a/platform/mbxxx/Makefile.mbxxx b/platform/mbxxx/Makefile.mbxxx index 61513ba96..752b2576b 100644 --- a/platform/mbxxx/Makefile.mbxxx +++ b/platform/mbxxx/Makefile.mbxxx @@ -1,4 +1,4 @@ -ARCH= irq.c sensors.c acc-sensor.c button-sensor.c temperature-sensor.c mems.c contact-sensor.c +ARCH= irq.c sensors.c acc-sensor.c button-sensor.c temperature-sensor.c mems.c contact-sensor.c i2c.c eeprom.c CONTIKI_TARGET_DIRS = . dev diff --git a/platform/mbxxx/board.c b/platform/mbxxx/board.c index eb98c3e17..7ae833bb9 100644 --- a/platform/mbxxx/board.c +++ b/platform/mbxxx/board.c @@ -79,6 +79,7 @@ #include "hal/micro/cortexm3/mfg-token.h" #endif #include +#include "dev/i2c.h" const LedResourceType LedsMB851A[] = { { @@ -522,6 +523,7 @@ void halBoardPowerUp(void) if ((boardDescription->flags & BOARD_HAS_MEMS) || (boardDescription->flags & BOARD_HAS_EEPROM)) { halGpioConfig(PORTA_PIN(1), GPIOCFG_OUT_ALT_OD); halGpioConfig(PORTA_PIN(2), GPIOCFG_OUT_ALT_OD); + i2c_enable(); } /* Configure GPIO for ADC access (temp sensor) */ if (boardDescription->flags & BOARD_HAS_TEMP_SENSOR) { diff --git a/platform/mbxxx/dev/acc-sensor.c b/platform/mbxxx/dev/acc-sensor.c index fc3fe026b..0a5439ec6 100644 --- a/platform/mbxxx/dev/acc-sensor.c +++ b/platform/mbxxx/dev/acc-sensor.c @@ -57,55 +57,53 @@ static int active(void) { uint8_t reg; - if(!i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR,CTRL_REG1, ®, 1)) + if(!MEMS_Read_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, ®, 1)) return FALSE; - + return (reg & 0x40) ? TRUE : FALSE ; } /*---------------------------------------------------------------------------*/ static int value(int type) { - int8_t i2c_data = 0; uint8_t reg_addr; - + switch(type) { case ACC_X_AXIS: reg_addr = OUTX_H; break; - + case ACC_Y_AXIS: reg_addr = OUTY_H; break; - + case ACC_Z_AXIS: reg_addr = OUTZ_H; break; - + default: - return 0; - } - - i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, reg_addr, (uint8_t *)&i2c_data, 1); - - if(MEMS_GetFullScale()==ACC_HIGH_RANGE){ - return ((int16_t)i2c_data)*HIGH_RANGE_SENSITIVITY; - } - else { - return ((int16_t)i2c_data)*LOW_RANGE_SENSITIVITY; + return 0; } + MEMS_Read_Reg(kLIS3L02DQ_SLAVE_ADDR, reg_addr, (uint8_t *)&i2c_data, 1); + + if(MEMS_GetFullScale()==ACC_HIGH_RANGE){ + return ((int16_t)i2c_data) * HIGH_RANGE_SENSITIVITY; + } + else { + return ((int16_t)i2c_data) * LOW_RANGE_SENSITIVITY; + } } /*---------------------------------------------------------------------------*/ static int configure(int type, int value) { switch(type) { - + case SENSORS_HW_INIT: - return Mems_Init(); - + return MEMS_Init(); + case SENSORS_ACTIVE: if(value){ if(MEMS_On()){ @@ -115,17 +113,18 @@ configure(int type, int value) return 0; } else - return MEMS_Off(); - + return MEMS_Off(); + case ACC_RANGE: return MEMS_SetFullScale((boolean)value); - - case ACC_HPF: + + case ACC_HPF: if(value < ACC_HPF_DISABLE){ - return i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (1<<4) | (uint8_t)value); + return MEMS_Write_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, + (1<<4) | (uint8_t)value); } else { - return i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00); + return MEMS_Write_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00); } } return 0; @@ -135,18 +134,15 @@ static int status(int type) { switch(type) { - + case SENSORS_READY: return active(); } - + return 0; } /*---------------------------------------------------------------------------*/ -SENSORS_SENSOR(acc_sensor, ACC_SENSOR, - value, configure, status); - - +SENSORS_SENSOR(acc_sensor, ACC_SENSOR, value, configure, status); /** @} */ diff --git a/platform/mbxxx/dev/eeprom.c b/platform/mbxxx/dev/eeprom.c new file mode 100644 index 000000000..4932787da --- /dev/null +++ b/platform/mbxxx/dev/eeprom.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2013, IDentification Automation Laboratory + * IDALab (http://www.idalab.unisalento.it) + * Department of Innovation Engineering - University of Salento + * + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file eeprom.c + * \brief ST M24C64W EEPROM driver. + * \author Maria Laura Stefanizzi + * \date 2013-11-20 + */ + +#include PLATFORM_HEADER +#include +#include + + +#define EE_HW_ADDRESS 0xA0 +#define EE_PAGESIZE 32 +#define EE_PAGEMASK 0x1F +#define EE_MAX_TRIALS 300 + +/* Write Cycle polling + * + * During the internal Write cycle, the device disconnects itself from the bus, + * and writes a copy of the data from its internal latches to the memory cells. + */ +static inline void +eeprom_wait(void) +{ + uint32_t trials = 0; + + /* Keep looping till the slave acknowledge his address or maximum number of + trials is reached */ + do { + /* Generate start */ + i2c_start(); + + /* Device select in in write mode */ + i2c_write(EE_HW_ADDRESS | 0x0); + + /* Check if the maximum allowed number of trials has been reached */ + if(trials++ == EE_MAX_TRIALS) { + /* If the maximum number of trials has been reached, exit the function */ + break; + } + } while((SC2_STAT(SC_TWIRXNAK)) == SC_TWIRXNAK); + /* eeprom reply with an ACK then it has terminated the internal Write cycle */ + + i2c_stop(); +} + +/** + * eeprom initializzation function + */ +void +eeprom_init(void) +{ + /* Nothing must be done here */ +} + +/** + * Write data to eeprom + * @param addr The eeprom memory address + * @param buf It is the buffer of bytes that will be written to the eeprom + * @param size It is the number of byte to write + */ +void +eeprom_write(eeprom_addr_t addr, unsigned char *buf, int size) +{ + unsigned int i = 0; + unsigned int curaddr; + + curaddr = addr; + for(i = 0; i < size; i++) { + /* If we are writing the first byte or are on a EE_PAGEMASK page boundary + we have to start a new write. */ + if(i == 0 || (curaddr & EE_PAGEMASK) == 0) { + + i2c_start(); + i2c_write(EE_HW_ADDRESS | 0x0); + + /* Write the new address to the bus. */ + i2c_write((curaddr & 0xFF00) >> 8); + i2c_write(curaddr & 0xFF); + } + + /* Write byte. */ + i2c_write(buf[i] & 0xFF); + + /* If we are writing the last byte totally or of a 32b page + generate a stop condition */ + if(i == size - 1 || (curaddr & EE_PAGEMASK) == EE_PAGEMASK) { + i2c_stop(); + eeprom_wait(); + } + + curaddr++; + } +} + +/** + * Read data from eeprom + * @param addr The eeprom memory address + * @param buf It is the destination buffer in witch the bytes will be written + * @param size It is the number of byte to read + */ +void +eeprom_read(eeprom_addr_t addr, unsigned char *buf, int size) +{ + uint8_t i; + + i2c_start(); + + /* Select eeprom with write mode bit enabled */ + i2c_write(EE_HW_ADDRESS | 0x0); + + /* Send address */ + i2c_write((addr & 0xFF00) >> 8); + i2c_write(addr & 0xFF); + + i2c_start(); + + /* Select eeprom with write mode bit disabled */ + i2c_write(EE_HW_ADDRESS | 0x1); + + for(i = 0; i < size; i++) { + if(i < (size - 1)) { + /* Read data and send ACK */ + *(buf + i) = i2c_read(1); + } else { + /* Last data, don't send ACK */ + *(buf + i) = i2c_read(0); + } + } + + i2c_stop(); +} + +/** @} */ diff --git a/platform/mbxxx/dev/i2c.c b/platform/mbxxx/dev/i2c.c new file mode 100644 index 000000000..96fb46a84 --- /dev/null +++ b/platform/mbxxx/dev/i2c.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2013, IDentification Automation Laboratory + * IDALab (http://www.idalab.unisalento.it) + * Department of Innovation Engineering - University of Salento + * + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file i2c.c + * \brief I2C bus master driver for mbxxx platform. + * \author Maria Laura Stefanizzi + * \date 2013-11-20 + */ + +#include +#include +#include "dev/i2c.h" +#include PLATFORM_HEADER + +#define WAIT_FIN_SC2(FLAG) while(!SC2_STAT(FLAG)) {} + +/** + * Configure serial controller in I2C mode and set I2C speed. + */ +void +i2c_enable(void) +{ + /* Configure serial controller to I2C mode */ + SC2_MODE = SC2_MODE_I2C; + + /* + * The SCL is produced by dividing down 12MHz according to + * this equation: + * Rate = 12 MHz / ( (LIN + 1) * (2^EXP) ) + * + * Configure rate registers for Fast Mode operation (400 kbps) + */ + SC2_RATELIN = 14; + SC2_RATEEXP = 1; + + /* Reset control registers */ + SC2_TWICTRL1 = SC2_TWICTRL1_RESET; + SC2_TWICTRL2 = SC2_TWICTRL2_RESET; +} + +/** + * Configure serial controller in disabled mode + */ +void +i2c_disable(void) +{ + SC2_MODE = SC2_MODE_DISABLED; +} + +/** + * Generate I2C START condition + */ +void +i2c_start(void) +{ + SC2_TWICTRL1 |= SC_TWISTART; + WAIT_FIN_SC2(SC_TWICMDFIN); +} + +/** + * Generate I2C STOP condition + */ +void +i2c_stop(void) +{ + SC2_TWICTRL1 |= SC_TWISTOP; + WAIT_FIN_SC2(SC_TWICMDFIN); +} + +/** + * Send a byte to I2C bus + * @param data The data that must be sent + */ +void +i2c_write(uint8_t data) +{ + SC2_DATA = data; + + /* Configure control register 1 for byte transmission */ + SC2_TWICTRL1 |= SC_TWISEND; + WAIT_FIN_SC2(SC_TWITXFIN); +} + +/** + * Read a byte from I2C bus + * @param ack If true enable ACK generation after byte reception + * @return The received byte + */ +uint8_t +i2c_read(int ack) +{ + if(ack) { + /* Enable ACK generation after current received byte */ + SC2_TWICTRL2 |= SC_TWIACK; + } else { + /* Disable ACK generation */ + SC2_TWICTRL2 &= ~SC_TWIACK; + } + + /* Configure control register 1 for byte reception */ + SC2_TWICTRL1 |= SC_TWIRECV; + WAIT_FIN_SC2(SC_TWIRXFIN); + + return SC2_DATA; +} diff --git a/platform/mbxxx/dev/i2c.h b/platform/mbxxx/dev/i2c.h new file mode 100644 index 000000000..c85bc6d8b --- /dev/null +++ b/platform/mbxxx/dev/i2c.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, IDentification Automation Laboratory + * IDALab (http://www.idalab.unisalento.it) + * Department of Innovation Engineering - University of Salento + * + * 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 Institute 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 INSTITUTE 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 INSTITUTE 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. + * + */ + +/** + * \file i2c.h + * \brief I2C bus master driver for mbxxx platform. + * \author Maria Laura Stefanizzi + * \date 2013-11-20 + */ +#ifndef I2C_H +#define I2C_H + +#define SC2_STAT(FLAG) (SC2_TWISTAT & FLAG) + +void i2c_enable(void); +void i2c_disable(void); +void i2c_start(void); +void i2c_stop(void); + +void i2c_write(uint8_t data); +uint8_t i2c_read(int ack); + +#endif /* I2C_H */ + diff --git a/platform/mbxxx/dev/mems.c b/platform/mbxxx/dev/mems.c index 95409fac0..5f74f1e43 100644 --- a/platform/mbxxx/dev/mems.c +++ b/platform/mbxxx/dev/mems.c @@ -23,205 +23,19 @@ #include PLATFORM_HEADER #include "mems.h" #include "timer.h" +#include "i2c.h" /* Private define -- ---------------------------------------------------------*/ - -#define TIMEOUT 20000 - #define SUCCESS 1 -#define FAIL 0 - -#define SEND_BYTE(data) do{ SC2_DATA=(data); SC2_TWICTRL1 |= SC_TWISEND; }while(0) - -#define WAIT_CMD_FIN() { \ - struct timer t; \ - timer_set(&t, CLOCK_SECOND/100); \ - while((SC2_TWISTAT&SC_TWICMDFIN)!=SC_TWICMDFIN){ \ - if(timer_expired(&t)){ \ - return FAIL; \ - } \ - } \ - } - -#define WAIT_TX_FIN() { \ - struct timer t; \ - timer_set(&t, CLOCK_SECOND/100); \ - while((SC2_TWISTAT&SC_TWITXFIN)!=SC_TWITXFIN){ \ - if(timer_expired(&t)){ \ - return FAIL; \ - } \ - } \ - } -#define WAIT_RX_FIN() { \ - struct timer t; \ - timer_set(&t, CLOCK_SECOND/100); \ - while((SC2_TWISTAT&SC_TWIRXFIN)!=SC_TWIRXFIN){ \ - if(timer_expired(&t)){ \ - return FAIL; \ - } \ - } \ - } +#define FAIL 0 /* Private variables ---------------------------------------------------------*/ static boolean fullscale_state; -/* Private functions ---------------------------------------------------------*/ -static uint8_t I2C_MEMS_Init (void); -//extern void halInternalResetWatchDog(void); -static uint8_t I2C_Send_Frame (uint8_t DeviceAddress, uint8_t *pBuffer, uint8_t NoOfBytes); -uint8_t i2c_write_reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t reg_value); -//static uint8_t I2C_MEMS_Read (t_mems_data *mems_data); - /* Functions -----------------------------------------------------------------*/ /******************************************************************************* -* Function Name : Mems_Init -* Description : It inits mems -* Input : None -* Output : status -* Return : None -*******************************************************************************/ -uint8_t Mems_Init(void) -{ - uint8_t ret = 0; - - // GPIO assignments - // PA1: SC2SDA (Serial Data) - // PA2: SC2SCL (Serial Clock) - - //-----SC2 I2C Master GPIO configuration - - TIM2_CCER &= 0xFFFFEEEE; - SC2_MODE = SC2_MODE_I2C; - GPIO_PACFGL &= 0xFFFFF00F; - GPIO_PACFGL |= 0x00000DD0; - - SC2_RATELIN = 14; // generates standard 100kbps or 400kbps - SC2_RATEEXP = 1; // 3 yields 100kbps; 1 yields 400kbps - SC2_TWICTRL1 = 0; // start from a clean state - SC2_TWICTRL2 = 0; // start from a clean state - - ret = I2C_MEMS_Init(); - - fullscale_state = MEMS_LOW_RANGE; - -//Add later if really needed -#ifdef ST_DBG - if (!ret) - I2C_DeInit(MEMS_I2C); -#endif - - return ret; -}/* end Mems_Init */ - -/******************************************************************************* -* Function Name : Mems_GetValue -* Description : It returns the 3 mems acceleration values related to x,y,z -* axes in mems_data -* Input : mems_data -* Output : status -* Return : None -*******************************************************************************/ -//uint8_t Mems_GetValue(t_mems_data *mems_data) -//{ -// uint8_t i; -// i = I2C_MEMS_Read(mems_data); -// return i; -//} - - -/* Private Functions ---------------------------------------------------------*/ - -/******************************************************************************* -* Function Name : I2C_Send_Frame -* Description : It sends I2C frame -* Input : DeviceAddress is the destination device address -* pBUffer is the buffer data -* NoOfBytes is the number of bytes -* Output : None -* Return : 1 if the frame has been successfully sent, 0 otherwise. -*******************************************************************************/ -static uint8_t I2C_Send_Frame (uint8_t DeviceAddress, uint8_t *pBuffer, uint8_t NoOfBytes) -{ - uint8_t i, data; - - SC2_TWICTRL1 |= SC_TWISTART; // send start - WAIT_CMD_FIN(); - - SEND_BYTE(DeviceAddress); // send the address low byte - WAIT_TX_FIN(); - - // loop sending the data - for (i=0; i 1) - addr += REPETIR; - - SC2_TWICTRL1 |= SC_TWISTART; // send start - WAIT_CMD_FIN(); - - SEND_BYTE(slave_addr | 0x00); // send the address low byte - WAIT_TX_FIN(); - - SEND_BYTE(addr); - WAIT_TX_FIN(); - - SC2_TWICTRL1 |= SC_TWISTART; // send start - WAIT_CMD_FIN(); - - SEND_BYTE(slave_addr | 0x01); // send the address low byte - WAIT_TX_FIN(); - - // loop receiving the data - for (i=0;i 1) + addr += REPETIR; + + i2c_start(); + + /* send the address low byte */ + i2c_write(slave_addr | 0x00); + + i2c_write(addr); + + i2c_start(); + + /* send the address low byte */ + i2c_write(slave_addr | 0x01); + + /* loop receiving the data */ + for (i = 0; i < NoOfBytes; i++){ + + if (i < (NoOfBytes - 1)) + /* ack on receipt of data */ + ack = 1; + else + /* don't ack if last one */ + ack = 0; + + /* receive data */ + *(pBuffer+i) = i2c_read(ack); + } + + i2c_stop(); + + return SUCCESS; +}/* end MEMS_Read_Reg() */ /******************************************************************************* -* Function Name : I2C_MEMS_Init -* Description : It performs basic MEMS register writes for initialization -* purposes +* Function Name : MEMS_Init +* Description : It inits mems * Input : None -* Output : None -* Return : 1 if the device has been successfully initialized, 0 otherwise. +* Output : status +* Return : None *******************************************************************************/ -static uint8_t I2C_MEMS_Init (void) +uint8_t +MEMS_Init(void) { - uint8_t i = 0; - - i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00); //no flag - i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00); // all off - i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00); // all off - //i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, (1<<4) | (1<<1) | (1 << 0)); - - i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00); - //i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7); - i += i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87); - - if (i != 5) - return 0; + TIM2_CCER &= 0xFFFFEEEE; + MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, STATUS_REG, 0x00); //no flag + MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, FF_WU_CFG, 0x00); // all off + MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, DD_CFG, 0x00); // all off + MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG2, 0x00); + MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87); + fullscale_state = MEMS_LOW_RANGE; return 1; -}/* end I2C_MEMS_Init() */ +}/* end MEMS_Init */ /******************************************************************************* * Function Name : I2C_MEMS_On @@ -288,21 +140,23 @@ static uint8_t I2C_MEMS_Init (void) * Output : None * Return : 1 if the device has been successfully set to normal mode, 0 otherwise. *******************************************************************************/ -uint8_t MEMS_On (void) +uint8_t +MEMS_On (void) { - return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7); + return MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0xC7); } /******************************************************************************* -* Function Name : I2C_MEMS_Off +* Function Name : MEMS_Off * Description : It turn off the device. * Input : None * Output : None * Return : 1 if the device has been successfully set to power-down mode, 0 otherwise. *******************************************************************************/ -uint8_t MEMS_Off (void) +uint8_t +MEMS_Off (void) { - return i2c_write_reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87); + return MEMS_Write_Reg (kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, 0x87); } /******************************************************************************* @@ -312,13 +166,13 @@ uint8_t MEMS_Off (void) * Output : None * Return : 1 if the device has been successfully set to full scale mode, 0 otherwise. *******************************************************************************/ -uint8_t MEMS_SetFullScale (boolean range) +uint8_t +MEMS_SetFullScale (boolean range) { uint8_t i2c_buffer; - - if(!i2c_read_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1)) - return 0; - + + MEMS_Read_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, &i2c_buffer, 1); + if(range==MEMS_HIGH_RANGE){ i2c_buffer |= 0x20; } @@ -326,49 +180,26 @@ uint8_t MEMS_SetFullScale (boolean range) i2c_buffer &= ~0x20; } - if(!i2c_write_reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer)) - return 0; - + MEMS_Write_Reg(kLIS3L02DQ_SLAVE_ADDR, CTRL_REG1, i2c_buffer); + fullscale_state = range; - + return 1; - } /******************************************************************************* -* Function Name : I2C_MEMS_GetFullScale +* Function Name : MEMS_GetFullScale * Description : It get the full-scale range of the device. * Input : None * Output : None * Return : range HIGH for high scale selection, LOW for low range. *******************************************************************************/ -boolean MEMS_GetFullScale (void) -{ +boolean +MEMS_GetFullScale (void) +{ return fullscale_state; } -/******************************************************************************* -* Function Name : I2C_MEMS_Read -* Description : It reads 3 axes acceleration data from mems -* Input : None -* Output : mems_data -* Return : 1 if acceleration data has been successfully read, 0 otherwise -*******************************************************************************/ -//static uint8_t I2C_MEMS_Read (t_mems_data *mems_data) -//{ -// uint8_t i, i2c_buffer[8]; -// -// i = i2c_read_reg (kLIS3L02DQ_SLAVE_ADDR, OUTX_L, i2c_buffer, 8); -// -// mems_data->outx_h = i2c_buffer[0]; -// mems_data->outx_l = i2c_buffer[1]; -// mems_data->outy_h = i2c_buffer[2]; -// mems_data->outy_l = i2c_buffer[3]; -// mems_data->outz_h = i2c_buffer[4]; -// mems_data->outz_l = i2c_buffer[5]; -// -// return i; -//}/* end I2C_MEMS_Read() */ - /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ /** @} */ + diff --git a/platform/mbxxx/dev/mems.h b/platform/mbxxx/dev/mems.h index c200ac373..b41fe43a5 100644 --- a/platform/mbxxx/dev/mems.h +++ b/platform/mbxxx/dev/mems.h @@ -49,17 +49,19 @@ typedef struct { /* Functions -----------------------------------------------------------------*/ /* Mems Initialization function */ -uint8_t Mems_Init(void); +uint8_t MEMS_Init(void); uint8_t MEMS_On(void); uint8_t MEMS_Off(void); uint8_t MEMS_SetFullScale(boolean range); boolean MEMS_GetFullScale(void); - -/* Get mems acceleration values */ -uint8_t Mems_GetValue(t_mems_data *mems_data); +uint8_t MEMS_Read_Reg (uint8_t slave_addr, uint8_t reg_addr, uint8_t *pBuffer, + uint8_t NoOfBytes); +uint8_t MEMS_Write_Reg (uint8_t slave_addr, uint8_t reg_addr, + uint8_t reg_value); #endif /*MEMS_H_ */ /******************* (C) COPYRIGHT 2009 STMicroelectronics *****END OF FILE****/ /** @} */ + diff --git a/platform/mbxxx/platform-conf.h b/platform/mbxxx/platform-conf.h index 6d56f3d41..5ed278687 100644 --- a/platform/mbxxx/platform-conf.h +++ b/platform/mbxxx/platform-conf.h @@ -54,7 +54,7 @@ #include PLATFORM_HEADER #include -#include // For memcpm(). +#include // For memcpm(). /* Platform-dependent definitions */ #define CC_CONF_REGISTER_ARGS 0 @@ -84,6 +84,7 @@ typedef unsigned long clock_time_t; #define CLOCK_CONF_SECOND 1000 typedef unsigned long rtimer_clock_t; + #define RTIMER_CLOCK_LT(a,b) ((signed short)((a)-(b)) < 0) #define LEDS_CONF_RED_PIN boardDescription->io->leds[1].gpioPin @@ -97,6 +98,7 @@ typedef unsigned long rtimer_clock_t; #define UIP_ARCH_CHKSUM 0 #define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN +#define EEPROM_CONF_SIZE 8000 #endif /* PLATFORM_CONF_H_ */ /** @} */