Subversion Repositories idreammicro-avr

Compare Revisions

Ignore whitespace Rev 16 → Rev 17

/trunk/libraries/twi/test/SConscript
0,0 → 1,16
# Import environment set for target.
Import('env_target')
 
# Set target name.
TARGET = 'twi__test'
 
# Set source file.
sources = [
'twi__test.c'
]
 
# Build project and libraries.
env_target.BuildProject(sources, TARGET)
 
# Compute memory usage.
env_target.ComputeMemoryUsage(TARGET)
/trunk/libraries/twi/demo/SConscript
0,0 → 1,16
# Import environment set for target.
Import('env_target')
 
# Set target name.
TARGET = 'twi__demo'
 
# Set source file.
sources = [
'twi__demo.c'
]
 
# Build project and libraries.
env_target.BuildProject(sources, TARGET)
 
# Compute memory usage.
env_target.ComputeMemoryUsage(TARGET)
/trunk/libraries/twi/src/twi.c
0,0 → 1,426
/**************************************************************************//**
* \brief TWI library
* \author Copyright (C) 2009 Julien Le Sech - www.idreammicro.com
* \version 1.0
* \date 20090501
*
* This file is part of the iDreamMicro library.
*
* This library is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
******************************************************************************/
 
/**************************************************************************//**
* \file twi.c
******************************************************************************/
 
/******************************************************************************
* Header file inclusions.
******************************************************************************/
 
#include <twi/twi.h>
#include <useful/bits.h>
 
#include <avr/io.h>
#include <util/twi.h>
 
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
 
/******************************************************************************
* Private macros.
******************************************************************************/
 
/**************************************************************************//**
* \def TWI__MAX_FREQUENCY
* \brief Max frequency of TWI bus.
******************************************************************************/
#define TWI__MAX_FREQUENCY 400000
 
/******************************************************************************
* Private types.
******************************************************************************/
 
/**************************************************************************//**
* \enum twi__prescaler_values
* \brief Available TWI bus prescaler values.
*
* \typedef twi__prescaler_value_t
* \brief TWI bus prescaler value.
******************************************************************************/
typedef enum twi__prescaler_values
{
TWI__PRESCALER_VALUE__1,
TWI__PRESCALER_VALUE__4,
TWI__PRESCALER_VALUE__16,
TWI__PRESCALER_VALUE__64,
TWI__PRESCALER_VALUE__INVALID
} twi__prescaler_value_t;
 
/**************************************************************************//**
* \struct twi__prescaler_configuration
* \brief TWI bus prescaler configuration.
*
* \typedef twi__prescaler_configuration_t
* \brief TWI bus prescaler configuration.
******************************************************************************/
typedef struct twi__prescaler_configuration
{
uint8_t value;
uint8_t bits;
} twi__prescaler_configuration_t;
 
/******************************************************************************
* Private constant definitions.
******************************************************************************/
 
/**************************************************************************//**
* \var prescaler_configurations
* \brief Available prescaler configurations.
******************************************************************************/
static const twi__prescaler_configuration_t prescaler_configurations[] =
{
[TWI__PRESCALER_VALUE__1] =
{
.value = 1,
.bits = 0
},
[TWI__PRESCALER_VALUE__4] =
{
.value = 4,
.bits = _BV(TWPS0)
},
[TWI__PRESCALER_VALUE__16] =
{
.value = 16,
.bits = _BV(TWPS1)
},
[TWI__PRESCALER_VALUE__64] =
{
.value = 64,
.bits = _BV(TWPS1) | _BV(TWPS0)
}
};
 
/******************************************************************************
* Private function prototypes.
******************************************************************************/
 
/**************************************************************************//**
* \fn static inline uint8_t twi__compute_bit_rate(
* uint32_t f_scl,
* uint8_t prescaler_value)
*
* \brief
*
* \param f_scl SCL frequency.
* \param prescaler_value Prescaler value.
******************************************************************************/
static inline
uint8_t
twi__compute_bit_rate
(
uint32_t f_scl,
uint8_t prescaler_value
);
 
/******************************************************************************
* Public function definitions.
******************************************************************************/
 
/**************************************************************************//**
* \fn void twi__initialize(uint32_t frequency)
*
* \brief Initialize TWI.
*
* \param frequency TWI frequency (up to 400 kHz).
******************************************************************************/
void twi__initialize
(
uint32_t frequency
){
// Check the preconditions.
assert(TWI__MAX_FREQUENCY >= frequency);
 
uint16_t bit_rate = UINT16_MAX;
twi__prescaler_value_t prescaler_value = TWI__PRESCALER_VALUE__1;
 
// Compute bit rate and prescaler value.
do
{
bit_rate = twi__compute_bit_rate
(
frequency,
prescaler_configurations[prescaler_value].value
);
} while (UINT8_MAX < bit_rate && TWI__PRESCALER_VALUE__INVALID > prescaler_value++);
 
// Set bit rate.
TWBR = bit_rate;
 
// Set prescaler value.
TWSR = prescaler_configurations[prescaler_value].bits;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__start(void)
*
* \brief
******************************************************************************/
twi__error_t
twi__start
(
void
){
// Send start condition.
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
 
// Wait for TWINT flag set. This indicates that the START condition has
// been transmitted.
while (!(TWCR & (1 << TWINT)));
 
// Check value of TWI Status Register. Mask prescaler bits.
if (TWSR & TW_NO_INFO != TW_START)
{
// If status is different from START (TW_START), return error.
return TWI__ERROR__ERROR;
}
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__repeat_start(void)
*
* \brief
******************************************************************************/
twi__error_t
twi__repeat_start
(
void
){
// TODO: check if TWSTO must be set.
// Send start condition.
TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWSTA) | (1 << TWSTO);
 
// Wait for TWINT flag set. This indicates that the START condition has
// been transmitted.
while (!(TWCR & (1 << TWINT)));
 
// Check value of TWI Status Register. Mask prescaler bits.
if (TWSR & TW_NO_INFO != TW_REP_START)
{
// If status different from START (TW_REP_START), return error.
return TWI__ERROR__ERROR;
}
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__send_slar(uint8_t sla)
*
* \brief
*
* \param sla
******************************************************************************/
twi__error_t
twi__send_slar
(
uint8_t sla
){
// Load SLA into TWDR register.
TWDR = sla | TW_READ;
 
// Clear TWINT bit in TWCR to start transmission of address.
TWCR = (1 << TWINT) | (1 << TWEN);
 
// Wait for TWINT flag set. This indicates that the SLA+W (TW_WRITE) has
// been transmitted, and ACK/NACK has been received.
while (!(TWCR & (1 << TWINT)));
 
// Check value of TWI Status Register. Mask prescaler bits. If status
// different from MT_SLA_ACK (TW_MR_SLA_ACK), return error.
if (TWSR & TW_NO_INFO != TW_MR_SLA_ACK)
{
return TWI__ERROR__ERROR;
}
 
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__send_slaw(uint8_t sla)
*
* \brief
*
* \param sla
******************************************************************************/
twi__error_t
twi__send_slaw
(
uint8_t sla
){
// Load SLA into TWDR register.
TWDR = sla | TW_WRITE;
 
// Clear TWINT bit in TWCR to start transmission of address.
TWCR = (1 << TWINT) | (1 << TWEN);
 
// Wait for TWINT flag set. This indicates that the SLA+W (TW_WRITE) has
// been transmitted, and ACK/NACK has been received.
while (!(TWCR & (1 << TWINT)));
 
// Check value of TWI Status Register. Mask prescaler bits. If status
// different from MT_SLA_ACK (TW_MT_SLA_ACK), return error.
if (TWSR & TW_NO_INFO != TW_MT_SLA_ACK)
{
return TWI__ERROR__ERROR;
}
 
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__send_data(uint8_t data)
*
* \brief
*
* \param data Data to send.
******************************************************************************/
twi__error_t
twi__send_data
(
uint8_t data
){
// Load data into TWDR register.
TWDR = data;
// Clear TWINT bit in TWCR to start transmission of data.
TWCR = (1 << TWINT) | (1 << TWEN);
 
// Wait for TWINT flag set. This indicates that the data has been
// transmitted, and ACK/NACK has been receiver.
while (!(TWCR & (1 << TWINT)));
 
// Check value of TWI status register. Mask prescaler bits. If status
// different from MT_DATA_ACK (TW_MT_DATA_ACK), return error.
if (TWSR & TW_NO_INFO != TW_MT_DATA_ACK)
{
return TWI__ERROR__ERROR;
}
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__receive_data_ack(uint8_t* p_data)
*
* \brief
*
* \param p_data
******************************************************************************/
twi__error_t
twi__receive_data_ack
(
uint8_t* p_data
){
// Check the preconditions.
assert(NULL != p_data);
 
TWCR = (1 << TWEN) | (1 << TWINT) | (1 << TWEA);
while (!(TWCR & (1 << TWINT)));
 
if ((TWSR & TW_NO_INFO) != TW_MR_DATA_ACK)
{
return TWI__ERROR__ERROR;
}
*p_data = TWDR;
 
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn twi__error_t twi__receive_data_nack(uint8_t* p_data)
*
* \brief
*
* \param p_data
******************************************************************************/
twi__error_t
twi__receive_data_nack
(
uint8_t* p_data
){
// Check the preconditions.
assert(NULL != p_data);
 
TWCR = (1 << TWEN) | (1 << TWINT);
while (!(TWCR & (1 << TWINT)));
 
if ((TWSR & TW_NO_INFO) != TW_MR_DATA_NACK)
{
return TWI__ERROR__ERROR;
}
*p_data = TWDR;
return TWI__ERROR__NONE;
}
 
/**************************************************************************//**
* \fn void twi__stop(void)
*
* \brief Stop TWI.
******************************************************************************/
void
twi__stop
(
void
){
// Transmit stop operation.
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
// Wait for stop.
while (TWCR & (1 << TWSTO));
}
 
/******************************************************************************
* Private function definitions.
******************************************************************************/
 
/**************************************************************************//**
* \fn static inline uint8_t twi__compute_bit_rate(
* uint32_t f_scl,
* uint8_t prescaler_value)
*
* \brief
*
* \param f_scl SCL frequency.
* \param prescaler_value Prescaler value.
******************************************************************************/
static inline
uint8_t
twi__compute_bit_rate
(
uint32_t f_scl,
uint8_t prescaler_value
){
uint8_t bit_rate = (F_CPU - 16 * f_scl) / (2 * f_scl * prescaler_value);
 
return bit_rate;
}
/trunk/libraries/twi/src/SConscript
0,0 → 1,13
# Import environment set for target.
Import('env_target')
 
# Define target name.
TARGET = 'twi'
 
# Define source files.
sources = [
'twi.c'
]
 
# Build library.
env_target.BuildLibrary(sources, TARGET)
/trunk/libraries/twi/SConscript
0,0 → 1,16
# Import environment set for target.
Import('env_target')
 
# Define directories to process.
directories = [
'src/'
]
 
# Process directories.
for directory in directories:
SConscript(
directory + 'SConscript',
variant_dir = '#build/' + '/libraries/twi/' + env_target['NAME'],
exports = { 'env_target' : env_target },
duplicate = 0
)
/trunk/libraries/twi/SConstruct
0,0 → 1,40
# Import build tools.
SConscript('#min_env/build_tools.py')
 
# Set environment for AVR-GCC.
SConscript('#min_env/env_target.py')
 
# Import environment set for AVR-GCC.
Import('env_target')
 
# Append CPPPATH.
env_target.Append(CPPPATH = [ '#../' ])
 
# Build library.
SConscript(
'src/SConscript',
variant_dir = '#build/lib/',
exports = { 'env_target' : env_target },
duplicate = 0
)
 
# Append LIBPATH and LIBS.
env_target.Append(LIBPATH = [ '#build/lib/'])
env_target.Append(LIBS = [ 'twi' ])
 
# Build demonstration program.
SConscript(
'demo/SConscript',
variant_dir = '#build/demo/',
exports = { 'env_target' : env_target },
duplicate = 0
)
 
# Build test program.
SConscript(
'test/SConscript',
variant_dir = '#build/test/',
exports = { 'env_target' : env_target },
duplicate = 0
)
 
/trunk/libraries/twi/twi.h
0,0 → 1,176
/**************************************************************************//**
* \brief TWI library
* \author Copyright (C) 2011 Julien Le Sech - www.idreammicro.com
* \version 1.0
* \date 20090501
*
* This file is part of the iDreamMicro library.
*
* This library is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see http://www.gnu.org/licenses/
******************************************************************************/
 
/**************************************************************************//**
* \headerfile twi.h
******************************************************************************/
 
#ifndef H__IDREAMMICRO__TWI__H
#define H__IDREAMMICRO__TWI__H
 
#ifdef _cplusplus
extern "C"{
#endif
 
/******************************************************************************
* Header file inclusions.
******************************************************************************/
 
#include <stdint.h>
 
/******************************************************************************
* Public type definitions.
******************************************************************************/
 
/**************************************************************************//**
* \typedef twi__error_t
*
* \brief TWI errors.
******************************************************************************/
// TODO: more errors.
typedef enum twi__errors
{
TWI__ERROR__NONE,
TWI__ERROR__ERROR,
TWI__ERROR__INVALID
} twi__error_t;
 
/******************************************************************************
* Public function prototypes.
******************************************************************************/
 
/**************************************************************************//**
* \fn void twi__initialize(uint32_t frequency)
*
* \brief Initialize TWI.
*
* \param frequency TWI frequency (up to 400 kHz).
******************************************************************************/
void
twi__initialize
(
uint32_t frequency
);
 
/**************************************************************************//**
* \fn twi__error_t twi__start(void)
*
* \brief
******************************************************************************/
twi__error_t
twi__start
(
void
);
 
/**************************************************************************//**
* \fn twi__error_t twi__repeat_start(void)
*
* \brief
******************************************************************************/
twi__error_t
twi__repeat_start
(
void
);
 
/**************************************************************************//**
* \fn twi__error_t twi__send_slar(uint8_t sla)
*
* \brief
*
* \param sla
******************************************************************************/
twi__error_t
twi__send_slar
(
uint8_t sla
);
 
/**************************************************************************//**
* \fn twi__error_t twi__send_slaw(uint8_t sla)
*
* \brief
*
* \param sla
******************************************************************************/
twi__error_t
twi__send_slaw
(
uint8_t sla
);
 
/**************************************************************************//**
* \fn twi__error_t twi__send_data(uint8_t data)
*
* \brief
*
* \param data Data to send.
******************************************************************************/
twi__error_t
twi__send_data
(
uint8_t data
);
 
/**************************************************************************//**
* \fn twi__error_t twi__receive_data_ack(uint8_t* p_data)
*
* \brief
*
* \param p_data
******************************************************************************/
twi__error_t
twi__receive_data_ack
(
uint8_t* p_data
);
 
/**************************************************************************//**
* \fn twi__error_t twi__receive_data_nack(uint8_t* p_data)
*
* \brief
*
* \param p_data
******************************************************************************/
twi__error_t
twi__receive_data_nack
(
uint8_t* p_data
);
 
/**************************************************************************//**
* \fn void twi__stop(void)
*
* \brief
******************************************************************************/
void
twi__stop
(
void
);
 
#ifdef _cplusplus
}
#endif
 
#endif /* H__IDREAMMICRO__TWI__H */
/trunk/libraries/twi/min_env/env_target.py
0,0 → 1,27
# Create and initialize the environment.
env_target = Environment()
 
# Set environment for AVR-GCC.
env_target['CC'] = 'avr-gcc'
env_target['CPPPATH'] = '/usr/lib/avr/include'
env_target['OBJCOPY'] = 'avr-objcopy'
env_target['SIZE'] = 'avr-size'
env_target['AR'] = 'avr-ar'
env_target['RANLIB'] = 'avr-ranlib'
env_target.Append(CCFLAGS = '-Os')
 
# Define environment name.
env_target.Append(NAME = 'env_target')
 
# Microcontroller type.
env_target.Append(MCU = 'atmega328p')
# Microcontroller frequency in Hertz.
env_target.Append(F_CPU = '16000000UL')
 
# Set environment for an Atmel AVR ATmega328p microcontroller.
env_target.Append(CCFLAGS = '-mmcu=' + env_target['MCU'])
env_target.Append(LINKFLAGS = '-mmcu=' + env_target['MCU'])
env_target.Append(CPPDEFINES = 'F_CPU=' + env_target['F_CPU'])
 
# Export environment set for target.
Export('env_target')
/trunk/libraries/twi/min_env/build_tools.py
0,0 → 1,41
"""
Build project.
"""
def BuildProject(env, sources, target_name):
# Build program.
env.Program(target = target_name + '.elf', source = sources)
# Create hex binary file.
env.Command(
target_name + '.hex',
target_name + '.elf',
env['OBJCOPY'] + ' -O ihex $SOURCE $TARGET'
)
AddMethod(Environment, BuildProject)
 
"""
Build library.
"""
def BuildLibrary(env, sources, target_name):
# Build static library.
env.StaticLibrary(target = target_name, source = sources)
# Append LIBPATH and LIBS.
env.Append(LIBPATH = [ '#build/libraries/' + target_name + '/' + env['NAME'] ])
env.Append(LIBS = [ target_name ])
 
AddMethod(Environment, BuildLibrary)
 
"""
Compute memory usage.
"""
def ComputeMemoryUsage(env, target_name):
# Compute memory usage.
env.Command(
None,
target_name + '.elf',
env['SIZE'] + ' -C --mcu=' + env['MCU'] + ' $SOURCE'
)
AddMethod(Environment, ComputeMemoryUsage)