aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorLars-Dominik Braun <lars@6xq.net>2014-01-30 14:31:34 +0100
committerLars-Dominik Braun <lars@6xq.net>2014-01-30 14:31:34 +0100
commit4ebf0dc69153c1f715f934a7abce4fdefbc4453f (patch)
treea41025b75c3b7e493efdb06c1db7b9e16f9ef5e9 /main.c
downloadhourglass-4ebf0dc69153c1f715f934a7abce4fdefbc4453f.tar.gz
hourglass-4ebf0dc69153c1f715f934a7abce4fdefbc4453f.tar.bz2
hourglass-4ebf0dc69153c1f715f934a7abce4fdefbc4453f.zip
Initial import
Diffstat (limited to 'main.c')
-rw-r--r--main.c359
1 files changed, 359 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..e5a1056
--- /dev/null
+++ b/main.c
@@ -0,0 +1,359 @@
+/* cpu freq */
+#define F_CPU 1000000
+
+#include <avr/io.h>
+#include <util/delay.h>
+#include <stdio.h>
+
+/* cpu runs at 1mhz */
+
+/* i2c device addresses */
+#define L2GD20 0b11010100
+#define L2GD20_WHOAMI 0xf
+#define L2GD20_CTRLREG1 0x20
+#define LIS302DL 0b00111000
+#define LIS302DL_WHOAMI 0xf
+
+/* i2c constants */
+#define TW_READ 1
+#define TW_WRITE 0
+#define TW_STATUS (TWSR & 0xF8)
+
+void twStart () {
+ /* disable stop, reset twint, enable start, enable i2c */
+ TWCR = (TWCR & ~(1 << TWSTO)) | (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
+}
+
+void twStop () {
+ /* disable start, reset twint, enable stop, enable i2c */
+ TWCR = (TWCR & ~(1 << TWSTA)) | (1 << TWINT) | (1 << TWSTO) | (1 << TWEN);
+}
+
+void twFlush () {
+ /* disable start/stop, reset twint, enable i2c */
+ TWCR = (TWCR & ~((1 << TWSTA) | (1 << TWSTO))) | (1 << TWINT) | (1 << TWEN);
+}
+
+void twWait () {
+ while (!(TWCR & (1 << TWINT)));
+}
+
+void twInit () {
+ /* set scl to 3.6 kHz (at 1Mhz CPU speed)*/
+ TWBR = 2;
+ TWSR |= 0x3; /* set prescaler to 64 */
+}
+
+void ledInit () {
+ /* set led1,led2 to output */
+ DDRB |= (1 << PB6) | (1 << PB7);
+ /* set led3,led4,led5,led6 to output */
+ DDRD |= (1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5);
+}
+
+/* show data with leds */
+void ledShow (unsigned char val) {
+ PORTB = (PORTB & ~((1 << PB6) | (1 << PB7))) | ((val & 0x3) << PB6);
+ PORTD = (PORTD & ~((1 << PD2) | (1 << PD3) | (1 << PD4) | (1 << PD5))) | (((val >> 2) & 0xf) << PD2);
+}
+
+void uartInit () {
+ /* Set baud rate (9600, double speed, at 1mhz) */
+ UBRR0H = 0;
+ UBRR0L = 12;
+ /* enable double speed mode */
+ UCSR0A = (1 << U2X0);
+ /* Enable receiver and transmitter */
+ UCSR0B = (1<<RXEN0)|(1<<TXEN0);
+ /* Set frame format: 8 data, 1 stop bit, even parity */
+ UCSR0C = (1<<UPM01) | (0 << UPM00) | (0<<USBS0)|(3<<UCSZ00);
+}
+
+/* blocking uart send
+ */
+void uartSend (unsigned char data) {
+ /* Wait for empty transmit buffer */
+ while (!( UCSR0A & (1<<UDRE0)));
+ /* Put data into buffer, sends the data */
+ UDR0 = data;
+}
+
+int uartPutc (char c, FILE *stream) {
+ if (c == '\n') {
+ uartSend ('\r');
+ }
+ uartSend (c);
+ return 0;
+}
+
+static FILE mystdout = FDEV_SETUP_STREAM (uartPutc, NULL, _FDEV_SETUP_WRITE);
+
+unsigned char uartReceive () {
+ /* Wait for data to be received */
+ while ( !(UCSR0A & (1<<RXC0)) );
+ /* Get and return received data from buffer */
+ return UDR0;
+}
+
+void cpuInit () {
+ /* enter change prescaler mode */
+ CLKPR = CLKPCE << 1;
+ /* write new prescaler = 8 (i.e. 1Mhz clock frequency) */
+ CLKPR = 0b00000011;
+}
+
+#if 0
+void test1 () {
+ while (1) {
+ unsigned char res = uartReceive ();
+ for (unsigned char i = 0; i < 3; i++) {
+ PORTB ^= (1 << PB6);
+ _delay_ms (1000);
+ }
+ /* no frame or parity error? */
+ if (!(UCSR0A & (1 << FE0)) && !(UCSR0A & (1 << UPE0))) {
+ ledShow (res);
+ }
+ uartSend (res);
+ /* check tx complete */
+ while ( !(UCSR0A & (1<<TXC0)) );
+ /* clear tx complete */
+ UCSR0A |= (1<<TXC0);
+ }
+}
+#endif
+
+#if 0
+void enumreg () {
+ printf ("enumerating registers\n");
+ unsigned char reg[] = {0xf, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
+ //unsigned char reg[] = {0xf, 0x20, 0x21, 0x22, 0x23, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2d, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
+ for (unsigned char i = 0; i < sizeof (reg)/sizeof(*reg); i++) {
+ printf ("start\n");
+ twStart ();
+ twWait ();
+ unsigned char status = 0x0;
+
+ /* check status code */
+ if ((status = TW_STATUS) == 0x8) {
+ printf ("start ok\nwriting dev address\n");
+
+ /* write device address and write bit */
+ TWDR = L2GD20 | TW_WRITE;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x18) {
+ printf ("ok\n");
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ printf ("writing subaddress %x\n", reg[i]);
+
+ /* write subaddress (actually i2c data) */
+ TWDR = reg[i];
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x28) {
+ printf ("ok\n");
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ printf ("starting again\n");
+
+ /* repeated start */
+ twStart ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x10) {
+ printf ("ok\n");
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ printf ("writing read request\n");
+
+ /* write device address and read bit */
+ TWDR = L2GD20 | TW_READ;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x40) {
+ printf ("ok\n");
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* clear twint and wait for response */
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x58) {
+ printf ("ok\n");
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+ unsigned char ret = TWDR;
+
+ printf ("register %x is %x\n", reg[i], ret);
+
+ twStop ();
+
+ printf ("done\n");
+
+ /* there is no way to tell whether stop has been sent or not, just wait */
+ _delay_ms (10);
+ } else {
+ printf ("fail\n");
+ }
+ }
+}
+#endif
+
+int main(void) {
+ cpuInit ();
+ ledInit ();
+ twInit ();
+ uartInit ();
+
+ /* redirect stdout */
+ stdout = &mystdout;
+
+ printf ("initialization done\n");
+
+ /* disable power-down-mode */
+ twStart ();
+ twWait ();
+ unsigned char status = 0x0;
+
+ /* check status code */
+ if ((status = TW_STATUS) == 0x8) {
+ /* write device address and write bit */
+ TWDR = L2GD20 | TW_WRITE;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x18) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* write subaddress (actually i2c data) */
+ TWDR = 0x20;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x28) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* write actual data */
+ TWDR = 0b00001111;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x28) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ twStop ();
+ _delay_ms (100);
+ } else {
+ printf ("write: start failed\n");
+ }
+
+ while (1) {
+ unsigned char reg[] = {0x28, 0x29, 0x2a, 0x2b, 0x2d};
+ unsigned char val[6];
+ //unsigned char reg[] = {0xf, 0x20, 0x21, 0x22, 0x23, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2d, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f};
+ for (unsigned char i = 0; i < sizeof (reg)/sizeof(*reg); i++) {
+ twStart ();
+ twWait ();
+ unsigned char status = 0x0;
+
+ /* check status code */
+ if ((status = TW_STATUS) == 0x8) {
+
+ /* write device address and write bit */
+ TWDR = L2GD20 | TW_WRITE;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x18) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* write subaddress (actually i2c data) */
+ TWDR = reg[i];
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x28) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* repeated start */
+ twStart ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x10) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* write device address and read bit */
+ TWDR = L2GD20 | TW_READ;
+ if (TWCR & (1 << TWWC)) {
+ printf("write collision\n");
+ }
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x40) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+
+ /* clear twint and wait for response */
+ twFlush ();
+ twWait ();
+ if ((status = TW_STATUS) == 0x58) {
+ } else {
+ printf ("fail with code %x\n", status);
+ }
+ unsigned char ret = TWDR;
+ val[i] = ret;
+
+ twStop ();
+
+ /* there is no way to tell whether stop has been sent or not, just wait */
+ _delay_ms (10);
+ } else {
+ printf ("fail with code %x\n", status);
+ _delay_ms (1000);
+ }
+ }
+ printf ("%i/%i/%i\n", (val[1] << 8) | val[0], (val[3] << 8) | val[2], (val[5] << 8) | val[4]);
+ }
+
+ while (1);
+}