1
0
mirror of git://projects.qi-hardware.com/antorcha.git synced 2024-11-01 09:24:05 +02:00

tornado/: use UART in SPI mode to send LED patterns (at 4 Mbps)

This commit is contained in:
Werner Almesberger 2012-11-23 14:50:01 -03:00
parent bef7d5debf
commit 7b766ed93c
5 changed files with 116 additions and 7 deletions

BIN
tornado/doc/lclk-1123.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -31,7 +31,7 @@ OBJCOPY = $(AVR_PREFIX)objcopy
#OBJDUMP = $(AVR_PREFIX)objdump
SIZE = $(AVR_PREFIX)size
OBJS = $(NAME).o $(COMMON_OBJS)
OBJS = $(NAME).o led.o $(COMMON_OBJS)
BOOT_OBJS = boot.o $(COMMON_OBJS)
COMMON_OBJS =

82
tornado/fw/led.c Normal file
View File

@ -0,0 +1,82 @@
/*
* fw/led.c - LED control
*
* Written 2012 by Werner Almesberger
* Copyright 2012 Werner Almesberger
*
* 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, or
* (at your option) any later version.
*/
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#define F_CPU 8000000UL
#include <util/delay.h>
#include "io.h"
#include "led.h"
void led_show(const uint8_t p[LED_BYTES])
{
uint8_t i;
for (i = 0; i != 8; i++) {
while (!(UCSR0A & (1 << UDRE0)));
UDR0 = p[i];
}
/*
* There doesn't seem to be any reliable way to synchronize with the
* end of the shift operation register that wouldn't cli/sei. Note
* that, since the receiver is disabled, we can't use the RX side for
* this purpose (as it is done in the atusb firmware).
*
* So instead we just wait for the worst-case delay, being one byte
* in the shift register and another byte in the transmit buffer,
* giving a total of 16 bits.
*
* This is a bit too pessimistic and produces a slight extra delay of
* about 1.8 us. (The whole pattern transmission takes 16 us.)
* See also ../doc/lclk-1123.png
*/
_delay_us(4); /* 16 bits at 4 MHz */
SET(LED_LCLK);
CLR(LED_LCLK);
}
void led_off(void)
{
static uint8_t zero[LED_BYTES];
led_show(zero);
}
void led_init(void)
{
CLR(LED_SCLK);
OUT(LED_SCLK);
CLR(LED_LCLK);
OUT(LED_LCLK);
UBRR0 = 0; /* maximum data rate */
UCSR0C =
1 << UMSEL01 | /* Master SPI */
1 << UMSEL00 |
1 << UDORD0 | /* MSB first */
0 << UCPHA0 | /* SPI Mode 0 */
0 << UCPOL0;
UCSR0B =
1 << TXEN0; /* enable transmitter */
UBRR0 = 0; /* the manual sez we need this */
led_off();
}

28
tornado/fw/led.h Normal file
View File

@ -0,0 +1,28 @@
/*
* fw/led.h - LED control
*
* Written 2012 by Werner Almesberger
* Copyright 2012 Werner Almesberger
*
* 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, or
* (at your option) any later version.
*/
#ifndef LED_H
#define LED_H
#include <stdint.h>
#define N_LEDS 64
#define LED_BYTES (N_LEDS/8)
void led_show(const uint8_t p[LED_BYTES]);
void led_off(void);
void led_init(void);
#endif /* !LED_H */

View File

@ -5,6 +5,7 @@
#include <util/delay.h>
#include "io.h"
#include "led.h"
#define HIGH(port) \
@ -38,9 +39,6 @@
#endif
#define N_LEDS 64
static void send(uint8_t pattern[N_LEDS/8])
{
uint8_t i, j, mask;
@ -96,7 +94,7 @@ static uint16_t adc(bool x)
int main(void)
{
static uint8_t p[N_LEDS/8];
static uint8_t p[LED_BYTES];
uint8_t mode = 0;
uint16_t n = 0, v;
@ -119,6 +117,7 @@ int main(void)
OUT(VDD);
#endif
led_init();
while (1) {
while (!PIN(SW_SW));
@ -149,9 +148,9 @@ int main(void)
p[(v >> 3) & 7] &= ~(1 << (v & 7));
else
p[(v >> 3) & 7] |= 1 << (v & 7);
send(p);
led_show(p);
n++;
}
_delay_ms(1);
_delay_ms(100);
}
}