kopia lustrzana https://github.com/fsphil/hadie
Add C328 support functions
rodzic
201c0d5b18
commit
ea5763b005
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
|
||||
PROJECT=hadie
|
||||
OBJECTS=hadie.o rtty.o rs8encode.o
|
||||
OBJECTS=hadie.o rtty.o rs8encode.o c328.o
|
||||
|
||||
# Serial device used for programming AVR
|
||||
TTYPORT=/dev/ttyACM0
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/* Interface to the C328 UART camera */
|
||||
|
||||
#include "config.h"
|
||||
#include <stdint.h>
|
||||
#include <avr/io.h>
|
||||
#include "c328.h"
|
||||
|
||||
/* >10ms timeout at 300 hz */
|
||||
#define CMD_TIMEOUT (4)
|
||||
|
||||
#define RXREADY (UCSR0A & (1 << RXC0))
|
||||
|
||||
/* Receive buffer */
|
||||
#define RXBUF_LEN (64)
|
||||
static uint8_t rxbuf[RXBUF_LEN];
|
||||
static uint8_t rxbuf_len = 0;
|
||||
|
||||
/* Expected package size */
|
||||
static uint8_t pkg_len = 64; /* Default is 64 according to datasheet */
|
||||
|
||||
/* Timeout counter */
|
||||
volatile static uint8_t timeout_clk = 0;
|
||||
|
||||
void inline c3_tick()
|
||||
{
|
||||
if(timeout_clk) timeout_clk--;
|
||||
}
|
||||
|
||||
static void tx_byte(uint8_t b)
|
||||
{
|
||||
/* Wait for empty transmit buffer */
|
||||
while(!(UCSR0A & (1 << UDRE0)));
|
||||
|
||||
/* Put data into buffer, sends the data */
|
||||
UDR0 = b;
|
||||
}
|
||||
|
||||
static uint8_t c3_rx(uint8_t timeout)
|
||||
{
|
||||
rxbuf_len = 0;
|
||||
|
||||
timeout_clk = timeout;
|
||||
while(timeout_clk)
|
||||
{
|
||||
if(!RXREADY) continue;
|
||||
rxbuf[rxbuf_len++] = UDR0;
|
||||
if(rxbuf_len == 6) break;
|
||||
}
|
||||
|
||||
if(rxbuf_len != 6) return(0); /* Timeout or incomplete response */
|
||||
if(rxbuf[0] != 0xAA) return(0); /* All responses should begin 0xAA */
|
||||
|
||||
/* Return the received command ID */
|
||||
return(rxbuf[1]);
|
||||
}
|
||||
|
||||
static void c3_tx(uint8_t cmd, uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4)
|
||||
{
|
||||
tx_byte(0xAA);
|
||||
tx_byte(cmd);
|
||||
tx_byte(a1);
|
||||
tx_byte(a2);
|
||||
tx_byte(a3);
|
||||
tx_byte(a4);
|
||||
}
|
||||
|
||||
static char c3_cmd(uint8_t cmd, uint8_t a1, uint8_t a2, uint8_t a3, uint8_t a4)
|
||||
{
|
||||
uint8_t r;
|
||||
|
||||
c3_tx(cmd, a1, a2, a3, a4);
|
||||
r = c3_rx(CMD_TIMEOUT);
|
||||
|
||||
/* Did we get an ACK for this command? */
|
||||
if(r != CMD_ACK || rxbuf[2] != cmd) return(-1);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void c3_init()
|
||||
{
|
||||
/* Do UART initialisation, port 0 @ 57600 baud for 7.3728 MHz clock */
|
||||
UBRR0H = 0;
|
||||
UBRR0L = 7;
|
||||
|
||||
/* Enable TX & RX */
|
||||
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
|
||||
|
||||
/* 8-bit, no parity and 1 stop bit */
|
||||
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
|
||||
}
|
||||
|
||||
char c3_sync()
|
||||
{
|
||||
char i;
|
||||
|
||||
/* Send the SYNC command until the camera responds, up to 60 */
|
||||
for(i = 0; i < 60; i++)
|
||||
{
|
||||
/* Send the sync and wait for an ACK */
|
||||
if(c3_cmd(CMD_SYNC, 0, 0, 0, 0) != 0) continue;
|
||||
|
||||
/* ACK should be followed by a SYNC */
|
||||
if(c3_rx(CMD_TIMEOUT) != CMD_SYNC) continue;
|
||||
|
||||
/* ACK the SYNC and return success code */
|
||||
c3_tx(CMD_ACK, CMD_SYNC, 0, 0, 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* If we got here, the camera failed to sync. Panic */
|
||||
return(-1);
|
||||
}
|
||||
|
||||
char c3_setup(uint8_t ct, uint8_t rr, uint8_t jr)
|
||||
{
|
||||
return(c3_cmd(CMD_INIT, 0, ct, rr, jr));
|
||||
}
|
||||
|
||||
char c3_set_package_size(uint16_t s)
|
||||
{
|
||||
char r;
|
||||
|
||||
if(s > RXBUF_LEN) return(-1);
|
||||
|
||||
r = c3_cmd(CMD_SET_PKG_SIZE, 0x08, s & 0xFF, s >> 8, 0);
|
||||
|
||||
if(r == 0) pkg_len = s;
|
||||
|
||||
return(r);
|
||||
}
|
||||
|
||||
char c3_snapshot(uint8_t st, uint16_t skip_frame)
|
||||
{
|
||||
return(c3_cmd(CMD_SNAPSHOT, st, skip_frame & 0xFF, skip_frame >> 8, 0));
|
||||
}
|
||||
|
||||
char c3_get_picture(uint8_t pt, uint16_t *length)
|
||||
{
|
||||
/* Send the command */
|
||||
if(c3_cmd(CMD_GET_PICTURE, pt, 0, 0, 0) != 0) return(-1);
|
||||
|
||||
/* The camera should now send a DATA message */
|
||||
if(c3_rx(CMD_TIMEOUT) != CMD_DATA) return(-1);
|
||||
|
||||
/* Get the file size from the DATA args */
|
||||
*length = rxbuf[9] + (rxbuf[10] << 8);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
char c3_get_package(uint16_t id, uint8_t **dst, uint16_t *length)
|
||||
{
|
||||
uint8_t checksum;
|
||||
uint16_t s;
|
||||
|
||||
rxbuf_len = 0;
|
||||
checksum = 0;
|
||||
s = pkg_len;
|
||||
|
||||
/* Get the package by sending an ACK */
|
||||
c3_tx(CMD_ACK, 0, 0, id & 0xFF, id >> 8);
|
||||
|
||||
/* The camera should immediatly start returning data */
|
||||
timeout_clk = CMD_TIMEOUT;
|
||||
while(timeout_clk && rxbuf_len < s)
|
||||
{
|
||||
if(!RXREADY) continue;
|
||||
|
||||
/* Read the byte and update checksum */
|
||||
checksum += rxbuf[rxbuf_len++] = UDR0;
|
||||
|
||||
if(rxbuf_len == 4)
|
||||
{
|
||||
/* Get the actual length of the package */
|
||||
s = rxbuf[2] + (rxbuf[3] << 8) + 6;
|
||||
if(s > pkg_len) return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Test for timeout or incomplete package */
|
||||
if(rxbuf_len < s) return(-1);
|
||||
|
||||
/* Test checksum */
|
||||
checksum -= rxbuf[rxbuf_len - 2];
|
||||
if(checksum != rxbuf[rxbuf_len - 2]) return(-1);
|
||||
|
||||
/* All done */
|
||||
*dst = rxbuf;
|
||||
*length = rxbuf_len;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
char c3_finish_picture()
|
||||
{
|
||||
c3_tx(CMD_ACK, 0, 0, 0xF0, 0xF0);
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
#ifndef INC_C328_H
|
||||
#define INC_C328_H
|
||||
|
||||
/* Commands */
|
||||
#define CMD_INIT 0x01
|
||||
#define CMD_GET_PICTURE 0x04
|
||||
#define CMD_SNAPSHOT 0x05
|
||||
#define CMD_SET_PKG_SIZE 0x06
|
||||
#define CMD_SET_BAUDRATE 0x07
|
||||
#define CMD_RESET 0x08
|
||||
#define CMD_POWER_OFF 0x09
|
||||
#define CMD_DATA 0x0A
|
||||
#define CMD_SYNC 0x0D
|
||||
#define CMD_ACK 0x0E
|
||||
#define CMD_NAK 0x0F
|
||||
#define CMD_SET_LIGHT_FREQUENCY 0x13
|
||||
|
||||
/* Colour Types */
|
||||
#define CT_2BIT_GRAY 0x01
|
||||
#define CT_4BIT_GRAY 0x02
|
||||
#define CT_8BIT_GRAY 0x03
|
||||
#define CT_12BIT_COLOUR 0x05
|
||||
#define CT_16BIT_COLOUR 0x06
|
||||
#define CT_JPEG 0x07
|
||||
|
||||
/* Preview Resolutions */
|
||||
#define PR_80x60 0x01
|
||||
#define PR_160x120 0x03
|
||||
|
||||
/* Snapshot resolutions */
|
||||
#define SR_80x64 0x01
|
||||
#define SR_160x128 0x03
|
||||
#define SR_320x240 0x05
|
||||
#define SR_640x480 0x07
|
||||
|
||||
/* Picture Type */
|
||||
#define PT_SNAPSHOT 0x01
|
||||
#define PT_PREVIEW 0x02
|
||||
#define PT_JPEG_PREVIEW 0x03
|
||||
|
||||
/* Snapshot Type */
|
||||
#define ST_JPEG 0x00
|
||||
#define ST_RAW 0x01
|
||||
|
||||
/* Baudrates (0xXXYY, XX = First Divider, YY = Second Divider) */
|
||||
#define BR_7200 0xFF01
|
||||
#define BR_9600 0xBF01
|
||||
#define BR_14400 0x7F01
|
||||
#define BR_19200 0x5F01
|
||||
#define BR_28800 0x3F01
|
||||
#define BR_38400 0x2F01
|
||||
#define BR_57600 0x1F01
|
||||
#define BR_115200 0x0F01
|
||||
#define BR_921600 0x0101 /* Undocumented */
|
||||
|
||||
/* Light Frequencies */
|
||||
#define LF_50HZ 0x00
|
||||
#define LF_60HZ 0x01
|
||||
|
||||
/* Errors */
|
||||
#define ERR_PICTURE_TYPE_ERROR 0x01
|
||||
#define ERR_PICTURE_UP_SCALE 0x02
|
||||
#define ERR_PICTURE_SCALE_ERROR 0x03
|
||||
#define ERR_UNEXPECTED_REPLY 0x04
|
||||
#define ERR_SEND_PICTURE_TIMEOUT 0x05
|
||||
#define ERR_UNEXPECTED_COMMAND 0x06
|
||||
#define ERR_SRAM_JPEG_TYPE_ERROR 0x07
|
||||
#define ERR_SRAM_JPEG_SIZE_ERROR 0x08
|
||||
#define ERR_PICTURE_FORMAT_ERROR 0x09
|
||||
#define ERR_PICTURE_SIZE_ERROR 0x0A
|
||||
#define ERR_PARAMETER_ERROR 0x0B
|
||||
#define ERR_SEND_REGISTER_TIMEOUT 0x0C
|
||||
#define ERR_COMMAND_ID_ERROR 0x0D
|
||||
#define ERR_PICTURE_NOT_READY 0x0F
|
||||
#define ERR_TRANSFER_PACKAGE_NUMBER_ERROR 0x10
|
||||
#define ERR_SET_TRANSFER_PACKAGE_SIZE_WRONG 0x11
|
||||
#define ERR_COMMAND_HEADER_ERROR 0xF0
|
||||
#define ERR_COMMAND_LENGTH_ERROR 0xF1
|
||||
#define ERR_SEND_PICTURE_ERROR 0xF5
|
||||
#define ERR_SEND_COMMAND_ERROR 0xFF
|
||||
|
||||
extern void inline c3_tick();
|
||||
|
||||
extern void c3_init();
|
||||
extern char c3_sync();
|
||||
|
||||
extern char c3_setup(uint8_t ct, uint8_t rr, uint8_t jr);
|
||||
extern char c3_set_package_size(uint16_t s);
|
||||
extern char c3_snapshot(uint8_t st, uint16_t skip_frame);
|
||||
extern char c3_get_picture(uint8_t pt, uint16_t *length);
|
||||
extern char c3_get_package(uint16_t id, uint8_t **dst, uint16_t *length);
|
||||
extern char c3_finish_picture();
|
||||
|
||||
#endif
|
6
rtty.c
6
rtty.c
|
@ -15,6 +15,9 @@
|
|||
#include <string.h>
|
||||
#include "rtty.h"
|
||||
|
||||
/* For camera timeout */
|
||||
#include "c328.h"
|
||||
|
||||
/* MARK = Upper tone, Idle, bit */
|
||||
#define TXPIN (1 << 0) /* PB0 */
|
||||
#define TXENABLE (1 << 1) /* PB1 */
|
||||
|
@ -48,6 +51,9 @@ ISR(TIMER0_COMPA_vect)
|
|||
else byte = pgm_read_byte(txbuf++);
|
||||
txlen--;
|
||||
}
|
||||
|
||||
/* Camera timeout tick */
|
||||
c3_tick();
|
||||
}
|
||||
|
||||
void rtx_init()
|
||||
|
|
Ładowanie…
Reference in New Issue