few things; mostly, I2C works now!; it was a hardware error
i had been leaving the RESET pin floating... this does not work. it must be externally biased - high, if you want the chip to work.. :) lolpartial-rewrite
parent
f49d503698
commit
b0b9335651
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// int main(void) {
|
void main(void) {
|
||||||
// return 0;
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
|
@ -8,67 +8,26 @@
|
||||||
|
|
||||||
// TODO: this is not working yet
|
// TODO: this is not working yet
|
||||||
|
|
||||||
#if 0 // this is not the one we want; but it has all the right info
|
|
||||||
#include "lib-other/peter-fleury/i2cmaster/i2cmaster.h"
|
|
||||||
|
|
||||||
// so we can say `TWI_ADDRESS|I2C_WRITE`
|
|
||||||
#define TWI_ADDRESS (MCP23018_TWI_ADDRESS<<1)
|
|
||||||
|
|
||||||
uint8_t mcp23018_ready; // false
|
|
||||||
|
|
||||||
uint8_t mcp23018_init(void) {
|
|
||||||
// declare vars
|
|
||||||
uint8_t error;
|
|
||||||
|
|
||||||
// see if the device is ready
|
// see if the device is ready
|
||||||
// - success: set `mcp23018_ready = true` and continue initializing
|
// - success: set `mcp23018_ready = true` and continue initializing
|
||||||
// - failure: return `error`; we can try again later
|
// - failure: return `error`; we can try again later
|
||||||
error = i2c_start(TWI_ADDRESS|I2C_WRITE);
|
|
||||||
if(error) {
|
|
||||||
return error;
|
|
||||||
} else {
|
|
||||||
mcp23018_ready = true;
|
|
||||||
i2c_stop(); // release bus
|
|
||||||
}
|
|
||||||
|
|
||||||
// set pin direction
|
// set pin direction
|
||||||
// - unused : input : 1
|
// - unused : input : 1
|
||||||
// - rows : output : 0
|
// - rows : output : 0
|
||||||
// - columns : input : 1
|
// - columns : input : 1
|
||||||
i2c_start_wait(TWI_ADDRESS|I2C_WRITE);
|
|
||||||
i2c_write(IODIRA); // start register address
|
|
||||||
i2c_write(0b11000000); // IODIRA
|
|
||||||
i2c_write(0b11111111); // IODIRB
|
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
// set pull-up
|
// set pull-up
|
||||||
// - unused : on : 1
|
// - unused : on : 1
|
||||||
// - rows : on : 1
|
// - rows : on : 1
|
||||||
// - columns : on : 1
|
// - columns : on : 1
|
||||||
i2c_start_wait(TWI_ADDRESS|I2C_WRITE);
|
|
||||||
i2c_write(GPPUA); // start register address
|
|
||||||
i2c_write(0b11111111); // GPPUA
|
|
||||||
i2c_write(0b11111111); // GPPUB
|
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
// set output pins high
|
// set output pins high
|
||||||
// - rows : high : 1
|
// - rows : high : 1
|
||||||
// - other : low : 0 (or ignored)
|
// - other : low : 0 (or ignored)
|
||||||
i2c_start_wait(TWI_ADDRESS|I2C_WRITE);
|
|
||||||
i2c_write(OLATA); // start register address
|
|
||||||
i2c_write(0b00111111); // OLATA
|
|
||||||
i2c_stop();
|
|
||||||
|
|
||||||
return 0; // success
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <util/twi.h>
|
#include <util/twi.h>
|
||||||
// #include "lib-other/arduino/arduino/libraries/Wire/utility/twi.h"
|
|
||||||
#include "lib-other/pjrc/blinky/print.h"
|
|
||||||
#include "lib-other/pjrc/blinky/usb_debug_only.h"
|
|
||||||
|
|
||||||
#define MCP23018_h_INCLUDE_PRIVATE
|
#define MCP23018_h_INCLUDE_PRIVATE
|
||||||
#include "mcp23018.h"
|
#include "mcp23018.h"
|
||||||
|
@ -86,27 +45,60 @@ uint8_t mcp23018_init(void) {
|
||||||
#define OLATA 0x14 // output latch register
|
#define OLATA 0x14 // output latch register
|
||||||
#define OLATB 0x15
|
#define OLATB 0x15
|
||||||
|
|
||||||
static void twi_init(void) {
|
|
||||||
// TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
// ----------------------------------------------------------------------------
|
||||||
TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
|
// dbg
|
||||||
// TWBR = ((F_CPU / 100000) - 16) / 2;
|
// ----------------------------------------------------------------------------
|
||||||
TWBR = 0xFF; //dbg
|
|
||||||
// TWCR = (1<<TWEA)|(1<<TWEN);
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#define blink_led(time1, time2) { \
|
||||||
|
/* Teensy 2.0 onboard LED on PD6
|
||||||
|
on high, off low */ \
|
||||||
|
PORTD |= (1<<6); \
|
||||||
|
_delay_ms(time1); \
|
||||||
|
PORTD &= ~(1<<6); \
|
||||||
|
_delay_ms(time2); \
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t twi_start(void) {
|
void blink_hex(uint8_t num) {
|
||||||
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
|
// initial blink (get ready)
|
||||||
|
blink_led(700, 200);
|
||||||
|
// 1st hex number
|
||||||
|
for (uint8_t i=0; i<(num/0x10); i++) {
|
||||||
|
blink_led(200, 100);
|
||||||
|
}
|
||||||
|
_delay_ms(400);
|
||||||
|
// 2nd hex number
|
||||||
|
for (uint8_t i=0; i<(num%0x10); i++) {
|
||||||
|
blink_led(200, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------- // TWI
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void twi_init(void) {
|
||||||
|
TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
||||||
|
TWBR = ((F_CPU / 400000) - 16) / 2;
|
||||||
|
// TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
|
||||||
|
// TWBR = 0xFF; //dbg
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t twi_start(void) {
|
||||||
|
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
|
||||||
while (!(TWCR & (1<<TWINT)));
|
while (!(TWCR & (1<<TWINT)));
|
||||||
if ((TWSR & 0xF8) != TW_START)
|
if ((TWSR & 0xF8) != TW_START)
|
||||||
return TWSR & 0xF8; // error
|
return TWSR & 0xF8; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
static void twi_stop(void) {
|
void twi_stop(void) {
|
||||||
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
||||||
while (!(TWCR & (1<<TWSTO)));
|
while (TWCR & (1<<TWSTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint8_t twi_send(uint8_t data) {
|
uint8_t twi_send(uint8_t data) {
|
||||||
TWDR = data;
|
TWDR = data;
|
||||||
TWCR = (1<<TWINT)|(1<<TWEN);
|
TWCR = (1<<TWINT)|(1<<TWEN);
|
||||||
while (!(TWCR & (1<<TWINT)));
|
while (!(TWCR & (1<<TWINT)));
|
||||||
|
@ -114,61 +106,22 @@ static uint8_t twi_send(uint8_t data) {
|
||||||
return TWSR & 0xF8; // error
|
return TWSR & 0xF8; // error
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hid_print_number_binary(uint8_t data) {
|
// ----------------------------------------------------------------------------
|
||||||
print("0b");
|
// init function
|
||||||
for(int8_t i=7; i>=0; i--) {
|
// ----------------------------------------------------------------------------
|
||||||
(data & (1<<i))
|
|
||||||
? pchar('1')
|
|
||||||
: pchar('0');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static void hid_print_number_hex(uint8_t data) {
|
|
||||||
print("0x"); phex(data);
|
|
||||||
}
|
|
||||||
static uint8_t try_address(uint8_t address) {
|
|
||||||
uint8_t error;
|
|
||||||
|
|
||||||
print("\naddress "); hid_print_number_binary(address);
|
|
||||||
twi_start();
|
|
||||||
error = twi_send(address);
|
|
||||||
twi_stop();
|
|
||||||
print(" error "); hid_print_number_hex(error);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t mcp23018_init(void) {
|
uint8_t mcp23018_init(void) {
|
||||||
uint8_t error, address;
|
uint8_t ret;
|
||||||
|
|
||||||
twi_init();
|
twi_init();
|
||||||
|
|
||||||
// send address, wait
|
twi_start();
|
||||||
for (uint8_t i=0b000; i<=0b111; i++) {
|
ret = twi_send( (MCP23018_TWI_ADDRESS<<1) | TW_WRITE );
|
||||||
address = (0b0100<<4)|(i<<1)|TW_WRITE;
|
ret = twi_send(IODIRA);
|
||||||
error = try_address(address);
|
ret = twi_send(0);
|
||||||
}
|
ret = twi_send(0);
|
||||||
address = 0;
|
ret = twi_send(0);
|
||||||
error = try_address(address);
|
|
||||||
// for (uint8_t i=0b0000000; i<=0b1111111; i++) {
|
|
||||||
// address = (i<<1)|TW_WRITE;
|
|
||||||
// error = try_address(address);
|
|
||||||
// if (! error == 0x20)
|
|
||||||
// return error;
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
blink_hex(ret);
|
||||||
|
|
||||||
// uint8_t data[3];
|
|
||||||
//
|
|
||||||
// twi_init();
|
|
||||||
// twi_setAddress(MCP23018_TWI_ADDRESS);
|
|
||||||
//
|
|
||||||
// data[0] = IODIRA;
|
|
||||||
// data[1] = 0b00000000; // IODIRA
|
|
||||||
// error = twi_writeTo(MCP23018_TWI_ADDRESS, data, 2, true);
|
|
||||||
//
|
|
||||||
// data[0] = OLATA; // start register address
|
|
||||||
// data[1] = 0b00000000; // OLATA
|
|
||||||
// twi_writeTo(MCP23018_TWI_ADDRESS, data, 2, true);
|
|
||||||
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,12 +37,17 @@
|
||||||
o10 19o
|
o10 19o
|
||||||
power_positive Vdd(Vcc) +11 18o
|
power_positive Vdd(Vcc) +11 18o
|
||||||
I2C SCL +12 17o
|
I2C SCL +12 17o
|
||||||
I2C SDA +13 16o
|
I2C SDA +13 16+ RESET (see note)
|
||||||
o14-------15+ ADDR (see note)
|
o14-------15+ ADDR (see note)
|
||||||
|
|
||||||
* notes:
|
* notes:
|
||||||
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
|
* ADDR (pin15): Set slave address to `0b0100000` by connecting to Vss(GND).
|
||||||
(The user-defined bits are the three least significant).
|
(The user-defined bits are the three least significant).
|
||||||
|
* RESET (pin16) must be externally biased. At least, this is true on the
|
||||||
|
MCP23017, so it seems like it should be true with the MCP23018. Since
|
||||||
|
we're not going to trigger it ourselves, we'll tie it high.
|
||||||
|
* <http://davidn.org/wp/?p=89>
|
||||||
|
* <http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1293498979>
|
||||||
|
|
||||||
## Notes about Registers
|
## Notes about Registers
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Documentation : Teensy 2.0
|
# Documentation : Teensy 2.0
|
||||||
|
|
||||||
|
|
||||||
## Pinouts and Pin assignments
|
## Pinouts and Pin assignments
|
||||||
|
|
||||||
* `+` indicates pin
|
* `+` indicates pin
|
||||||
|
@ -45,6 +46,7 @@
|
||||||
internal pull-ups are enough (see datasheet section 20.5.1), but i think
|
internal pull-ups are enough (see datasheet section 20.5.1), but i think
|
||||||
for this project we'll want external ones.
|
for this project we'll want external ones.
|
||||||
|
|
||||||
|
|
||||||
## Notes about Registers
|
## Notes about Registers
|
||||||
|
|
||||||
### General I/O (see datasheet section 10.2.1)
|
### General I/O (see datasheet section 10.2.1)
|
||||||
|
@ -101,6 +103,30 @@
|
||||||
* OCR = Output Compare Register
|
* OCR = Output Compare Register
|
||||||
* TCCR = Timer/Counter Control Register
|
* TCCR = Timer/Counter Control Register
|
||||||
|
|
||||||
|
|
||||||
|
## I²C Status Codes (for Master modes)
|
||||||
|
|
||||||
|
### Master Transmitter
|
||||||
|
|
||||||
|
* `0x08` A START condition has been transmitted
|
||||||
|
* `0x10` A repeated START condition has been transmitted
|
||||||
|
* `0x18` SLA+W has been transmitted; ACK has been received
|
||||||
|
* `0x20` SLA+W has been transmitted; NOT ACK has been received
|
||||||
|
* `0x28` Data byte has been transmitted; ACK has been received
|
||||||
|
* `0x30` Data byte has been transmitted; NOT ACK has been received
|
||||||
|
* `0x38` Arbitration lost in SLA+W or data bytes
|
||||||
|
|
||||||
|
### Master Receiver
|
||||||
|
|
||||||
|
* `0x08` A START condition has been transmitted
|
||||||
|
* `0x10` A repeated START condition has been transmitted
|
||||||
|
* `0x38` Arbitration lost in SLA+R or NOT ACK bit
|
||||||
|
* `0x40` SLA+R has been transmitted; ACK has been received
|
||||||
|
* `0x48` SLA+R has been transmitted; NOT ACK has been received
|
||||||
|
* `0x50` Data byte has been received; ACK has been returned
|
||||||
|
* `0x58` Data byte has been received; NOT ACK has been returned
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
|
||||||
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
Copyright © 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
|
|
|
@ -12,11 +12,7 @@ TARGET = ergodox-firmware
|
||||||
|
|
||||||
SRC = $(shell find -maxdepth 1 -name '*.c') \
|
SRC = $(shell find -maxdepth 1 -name '*.c') \
|
||||||
$(shell find ./keyboard -name '*.c') \
|
$(shell find ./keyboard -name '*.c') \
|
||||||
$(shell find ./lib -name '*.c') \
|
$(shell find ./lib -name '*.c')
|
||||||
./lib-other/peter-fleury/i2cmaster/twimaster.c \
|
|
||||||
./lib-other/pjrc/blinky/print.c \
|
|
||||||
./lib-other/pjrc/blinky/usb_debug_only.c \
|
|
||||||
./lib-other/arduino/arduino/libraries/Wire/utility/twi.c
|
|
||||||
|
|
||||||
|
|
||||||
EXTRAINCDIRS = .
|
EXTRAINCDIRS = .
|
||||||
|
|
102
src/test.c
102
src/test.c
|
@ -1,102 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
|
|
||||||
#include "lib-other/pjrc/blinky/print.h"
|
|
||||||
#include "lib-other/pjrc/blinky/usb_debug_only.h"
|
|
||||||
|
|
||||||
#include "lib/data-types.h"
|
|
||||||
|
|
||||||
#define TEENSY_2_0_h_INCLUDE_PRIVATE
|
|
||||||
#include "keyboard/ergodox/teensy-2-0.h"
|
|
||||||
|
|
||||||
int blink_leds(void);
|
|
||||||
int test_i2c(void);
|
|
||||||
int test_kb_teensy(void);
|
|
||||||
int main(void);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int main(void) {
|
|
||||||
teensy_init();
|
|
||||||
|
|
||||||
KB_LED1_SET_PERCENT(.03);
|
|
||||||
KB_LED2_SET_PERCENT(.03);
|
|
||||||
KB_LED3_SET_PERCENT(.03);
|
|
||||||
|
|
||||||
// blink_leds();
|
|
||||||
// print("--------------");
|
|
||||||
test_i2c();
|
|
||||||
print("--------------");
|
|
||||||
test_kb_teensy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int blink_leds(void) {
|
|
||||||
for (uint8_t i=0; i<3; i++) {
|
|
||||||
KB_LED1_SET(0x10);
|
|
||||||
KB_LED2_SET(0x20);
|
|
||||||
KB_LED3_SET(0xFF);
|
|
||||||
_delay_ms(500);
|
|
||||||
KB_LED1_SET(0x20);
|
|
||||||
KB_LED2_SET(0xFF);
|
|
||||||
KB_LED3_SET(0x10);
|
|
||||||
_delay_ms(500);
|
|
||||||
KB_LED1_SET(0xFF);
|
|
||||||
KB_LED2_SET(0x10);
|
|
||||||
KB_LED3_SET(0x20);
|
|
||||||
_delay_ms(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i=0; i<2; i++) {
|
|
||||||
KB_LED1_OFF;
|
|
||||||
KB_LED2_OFF;
|
|
||||||
KB_LED3_OFF;
|
|
||||||
_delay_ms(500);
|
|
||||||
KB_LED1_ON;
|
|
||||||
KB_LED2_ON;
|
|
||||||
KB_LED3_ON;
|
|
||||||
_delay_ms(500);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool counting_up = true;
|
|
||||||
for (uint8_t i=0;;) {
|
|
||||||
(counting_up) ? i++ : i--;
|
|
||||||
if (i == 0xFF)
|
|
||||||
counting_up = false;
|
|
||||||
else if (i == 0)
|
|
||||||
counting_up = true;
|
|
||||||
|
|
||||||
KB_LED1_SET(i/2);
|
|
||||||
KB_LED2_SET(i/2);
|
|
||||||
KB_LED3_SET(i/2);
|
|
||||||
_delay_ms(10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int test_i2c(void) {
|
|
||||||
usb_init();
|
|
||||||
_delay_ms(500); // just to be safe
|
|
||||||
|
|
||||||
uint8_t ret;
|
|
||||||
|
|
||||||
uint8_t len;
|
|
||||||
char str[10];
|
|
||||||
|
|
||||||
print("\nhello");
|
|
||||||
|
|
||||||
ret = teensy_init();
|
|
||||||
print("\nteensy_init() returned: 0x"); phex(ret);
|
|
||||||
|
|
||||||
ret = mcp23018_init();
|
|
||||||
print("\nmcp23018_init() returned: 0x"); phex(ret);
|
|
||||||
|
|
||||||
usb_debug_flush_output();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
int test_kb_teensy(void) {
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# This is mostly a stub at the moment, but I'm keeping it separate so I can
|
||||||
|
# mess with it later without changing the original
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
|
# Released under The MIT License (MIT) (see "license.md")
|
||||||
|
# Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
TARGET = test
|
||||||
|
|
||||||
|
EXTRAINCDIRS = .
|
||||||
|
|
||||||
|
TEENSY_MAKE = $(MAKE) -f '../lib-other/pjrc/blinky/Makefile' \
|
||||||
|
TARGET='$(TARGET)' \
|
||||||
|
EXTRAINCDIRS='$(EXTRAINCDIRS)'
|
||||||
|
|
||||||
|
.PHONY: test_pwm test_twi
|
||||||
|
|
||||||
|
test_pwm:
|
||||||
|
$(TEENSY_MAKE) all \
|
||||||
|
SRC='test_pwm.c'
|
||||||
|
|
||||||
|
test_twi:
|
||||||
|
$(TEENSY_MAKE) all \
|
||||||
|
SRC='test_twi.c'
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(TEENSY_MAKE) clean \
|
||||||
|
SRC='$(shell find -name '*.c')'
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Test the Teensy 2.0 PWM code (see `#include`s)
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#define TEENSY_2_0_h_INCLUDE_PRIVATE
|
||||||
|
#include "../keyboard/ergodox/teensy-2-0.h"
|
||||||
|
#include "../keyboard/ergodox/teensy-2-0.c"
|
||||||
|
|
||||||
|
|
||||||
|
#define bool uint8_t
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
teensy_init();
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<3; i++) {
|
||||||
|
KB_LED1_SET(0x10);
|
||||||
|
KB_LED2_SET(0x20);
|
||||||
|
KB_LED3_SET(0xFF);
|
||||||
|
_delay_ms(500);
|
||||||
|
KB_LED1_SET(0x20);
|
||||||
|
KB_LED2_SET(0xFF);
|
||||||
|
KB_LED3_SET(0x10);
|
||||||
|
_delay_ms(500);
|
||||||
|
KB_LED1_SET(0xFF);
|
||||||
|
KB_LED2_SET(0x10);
|
||||||
|
KB_LED3_SET(0x20);
|
||||||
|
_delay_ms(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i=0; i<2; i++) {
|
||||||
|
KB_LED1_OFF;
|
||||||
|
KB_LED2_OFF;
|
||||||
|
KB_LED3_OFF;
|
||||||
|
_delay_ms(500);
|
||||||
|
KB_LED1_ON;
|
||||||
|
KB_LED2_ON;
|
||||||
|
KB_LED3_ON;
|
||||||
|
_delay_ms(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool counting_up = true;
|
||||||
|
for (uint8_t i=0;;) {
|
||||||
|
(counting_up) ? i++ : i--;
|
||||||
|
if (i == 0xFF)
|
||||||
|
counting_up = false;
|
||||||
|
else if (i == 0)
|
||||||
|
counting_up = true;
|
||||||
|
|
||||||
|
KB_LED1_SET(i/2);
|
||||||
|
KB_LED2_SET(i/2);
|
||||||
|
KB_LED3_SET(i/2);
|
||||||
|
_delay_ms(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
* Test for ACK on address write (with a Teensy 2.0 and I/O expander)
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
|
* Released under The MIT License (MIT) (see "license.md")
|
||||||
|
* Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <util/twi.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
|
||||||
|
// processor frequency (from <http://www.pjrc.com/teensy/prescaler.html>)
|
||||||
|
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||||
|
#define CPU_16MHz 0x00
|
||||||
|
#define CPU_8MHz 0x01
|
||||||
|
#define CPU_4MHz 0x02
|
||||||
|
#define CPU_2MHz 0x03
|
||||||
|
#define CPU_1MHz 0x04
|
||||||
|
#define CPU_500kHz 0x05
|
||||||
|
#define CPU_250kHz 0x06
|
||||||
|
#define CPU_125kHz 0x07
|
||||||
|
#define CPU_62kHz 0x08
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// helper functions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#define blink_led(time1, time2) { \
|
||||||
|
/* Teensy 2.0 onboard LED on PD6
|
||||||
|
on high, off low */ \
|
||||||
|
PORTD |= (1<<6); \
|
||||||
|
_delay_ms(time1); \
|
||||||
|
PORTD &= ~(1<<6); \
|
||||||
|
_delay_ms(time2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------- // TWI
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void twi_init(void) {
|
||||||
|
TWSR &= ~( (1<<TWPS1)|(1<<TWPS0) );
|
||||||
|
TWBR = ((F_CPU / 100000) - 16) / 2;
|
||||||
|
// TWSR |= (1<<TWPS1)|(1<<TWPS0); //dbg
|
||||||
|
// TWBR = 0xFF; //dbg
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t twi_start(void) {
|
||||||
|
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA);
|
||||||
|
while (!(TWCR & (1<<TWINT)));
|
||||||
|
if ((TWSR & 0xF8) != TW_START)
|
||||||
|
return TWSR & 0xF8; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
void twi_stop(void) {
|
||||||
|
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
|
||||||
|
while (TWCR & (1<<TWSTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t twi_send(uint8_t data) {
|
||||||
|
TWDR = data;
|
||||||
|
TWCR = (1<<TWINT)|(1<<TWEN);
|
||||||
|
while (!(TWCR & (1<<TWINT)));
|
||||||
|
if ((TWSR & 0xF8) != TW_MT_SLA_ACK)
|
||||||
|
return TWSR & 0xF8; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// main
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
CPU_PRESCALE(CPU_16MHz);
|
||||||
|
uint8_t ret;
|
||||||
|
|
||||||
|
twi_init();
|
||||||
|
|
||||||
|
for (uint8_t i=0;; i+=2) { // try all even (write) addresses
|
||||||
|
twi_start();
|
||||||
|
ret = twi_send(i); // i = address
|
||||||
|
twi_stop();
|
||||||
|
|
||||||
|
if (ret == 0x18) // SLA+W sent; ACK received
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i == 0xFE) // all done
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// blink the return value
|
||||||
|
// --- initial blink (get ready)
|
||||||
|
blink_led(700, 200);
|
||||||
|
// --- 1st hex number
|
||||||
|
for (uint8_t i=0; i<(ret/0x10); i++) {
|
||||||
|
blink_led(200, 100);
|
||||||
|
}
|
||||||
|
_delay_ms(400);
|
||||||
|
// --- 2nd hex number
|
||||||
|
for (uint8_t i=0; i<(ret%0x10); i++) {
|
||||||
|
blink_led(200, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue