0,0 → 1,209 |
/***************************************************************************** |
* Copyright (C) 2009 Peter "woggle" Mack, mac@denich.net * |
* * |
* This program is free software; you can redistribute it and/or modify * |
* it under the terms of the GNU General Public License as published by * |
* the Free Software Foundation; either version 2 of the License. * |
* * |
* This program 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 General Public License for more details. * |
* * |
* You should have received a copy of the GNU General Public License * |
* along with this program; if not, write to the * |
* Free Software Foundation, Inc., * |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * |
* * |
*****************************************************************************/ |
|
#include <avr/io.h> |
#include <avr/interrupt.h> |
#include <avr/pgmspace.h> |
#include <string.h> |
#include <util/twi.h> |
|
#include "main.h" |
#include "motortestI2C.h" |
#include "lcd.h" |
#include "usart.h" |
#include "timer.h" |
|
|
uint8_t m; |
|
|
#define SCL_FREQ 200000L |
|
#define I2C_STATE_TX_ADDRESS 0 |
#define I2C_STATE_TX_DATA 1 |
#define I2C_STATE_TX_STOP 2 |
#define I2C_STATE_RX_ADDRESS 3 |
#define I2C_STATE_RX_1BYTE 4 |
#define I2C_STATE_RX_2BYTE 5 |
|
volatile uint8_t i2c_state; |
uint8_t motor_addr_I2C = 0; |
|
//***************************************************************************** |
// |
void I2C_Init(void) |
{ |
uint8_t sreg = SREG; |
cli(); |
|
DDRC &= ~(1<<DDC1); // SDA is input |
DDRC |= (1<<DDC0); // SCL is output |
PORTC |= (1<<PORTC0)|(1<<PORTC1); // pull up SDA and SCL |
|
// prescaler 1 (TWPS1 = 0, TWPS0 = 0) |
TWSR &= ~((1<<TWPS1)|(1<<TWPS0)); |
|
TWBR = ((F_CPU/SCL_FREQ)-16)/2; |
|
i2c_state = I2C_STATE_TX_ADDRESS; |
|
SREG = sreg; |
} |
|
//***************************************************************************** |
// |
void I2C_Start(uint8_t start_state) |
{ |
i2c_state = start_state; |
|
// generate start condition and enable interrupts |
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN) | (1<<TWIE); |
} |
|
//***************************************************************************** |
// |
void I2C_Stop(uint8_t start_state) |
{ |
i2c_state = start_state; |
|
// generate stop condition and disable interrupt |
TWCR = (1<<TWINT) | (1<<TWSTO) | (1<<TWEN); |
} |
|
//***************************************************************************** |
// |
void I2C_WriteByte(int8_t b) |
{ |
TWDR = b; |
// clear interrupt flag (TWINT = 1) |
// enable i2c bus (TWEN = 1) |
// enable interrupt (TWIE = 1) |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); |
} |
|
//***************************************************************************** |
// |
void I2C_ReceiveByte(void) |
{ |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE) | (1<<TWEA); |
} |
|
//***************************************************************************** |
// |
void I2C_ReceiveLastByte(void) |
{ |
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWIE); |
} |
|
|
//***************************************************************************** |
// |
ISR (TWI_vect) |
{ |
int8_t mrCurrent; |
int8_t mrMaxpwm; |
|
switch (i2c_state++) |
{ |
// TWI Master Transmit |
case I2C_STATE_TX_ADDRESS: |
I2C_WriteByte(0x52 + (motor_addr_I2C * 2) ); // select slave adress in tx mode |
break; |
|
case I2C_STATE_TX_DATA: |
I2C_WriteByte(m); |
break; |
|
case I2C_STATE_TX_STOP: |
if(TWSR == TW_MT_DATA_NACK) // Data transmitted, NACK received |
{ |
// error occured |
} |
I2C_Stop(I2C_STATE_TX_ADDRESS); |
I2C_Start(I2C_STATE_RX_ADDRESS); // Repeated start -> switch slave or switch Master Transmit -> Master Receive |
break; |
|
// Master Receive Data |
case I2C_STATE_RX_ADDRESS: |
I2C_WriteByte(0x53 + (motor_addr_I2C * 2) ); // select slave adress in rx mode |
if(TWSR != TW_MR_SLA_ACK) // SLA+R transmitted, if not ACK received |
{ // no response from the addressed slave received |
I2C_Stop(I2C_STATE_TX_ADDRESS); |
} |
else |
{ |
I2C_ReceiveByte(); //Transmit 1st byte |
} |
break; |
|
case I2C_STATE_RX_1BYTE: //Read 1st byte and transmit 2nd Byte |
mrCurrent = TWDR; |
I2C_ReceiveLastByte(); // nack |
break; |
|
case I2C_STATE_RX_2BYTE: |
//Read 2nd byte |
mrMaxpwm = TWDR;; |
I2C_Stop(I2C_STATE_TX_ADDRESS); |
break; |
|
default: |
I2C_Stop(I2C_STATE_TX_ADDRESS); |
break; |
} |
} |
|
//***************************************************************************** |
// |
void motor_i2c (void) |
{ |
uint8_t blc = 0; |
|
lcd_cls (); |
m = 0; |
|
lcd_printp (PSTR("I2C Motor Test"), 0); |
lcd_printpns_at (0, 7, PSTR("dec inc Exit Oxff"), 0); |
|
lcd_printp (PSTR("BLC #"), 0); |
|
do |
{ |
if ((get_key_press (1 << KEY_PLUS) || get_key_rpt (1 << KEY_PLUS)) && (m < 254)) |
{ |
m++; |
} |
if ((get_key_press (1 << KEY_MINUS) || get_key_rpt (1 << KEY_MINUS)) && (m > 0)) |
{ |
lcd_frect (GX, GY, (m * 108) / 255, 10, 0); |
m--; |
} |
if (get_key_press (1 << KEY_ENTER)) |
{ |
lcd_frect (GX, GY, (m * 108) / 255, 10, 0); |
m = 0; |
} |
} |
while (!get_key_press (1 << KEY_ESC)); |
|
// switch all engines off at exit ! |
} |
|
|
|