forked from mfulz_github/qmk_firmware
Updated Benito project -- added hardware interrupt and software buffering for serial data reception to prevent missed characters, condensed pulse generation counters into a struct for clarity.
Added check to CDC_Device_BytesReceived() to ensure 0 is returned when device is not enumerated to a host. Move AVRISP project's V2Protocol_DelayMS() function to be static inline, as it is now very minimal. Added extra project doxygen documentation.
This commit is contained in:
parent
f070902bdb
commit
6d1adf7339
File diff suppressed because one or more lines are too long
|
@ -174,6 +174,9 @@ uint8_t CDC_Device_Flush(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||||
|
|
||||||
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
uint16_t CDC_Device_BytesReceived(USB_ClassInfo_CDC_Device_t* const CDCInterfaceInfo)
|
||||||
{
|
{
|
||||||
|
if ((USB_DeviceState != DEVICE_STATE_Configured) || !(CDCInterfaceInfo->State.LineEncoding.BaudRateBPS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
|
Endpoint_SelectEndpoint(CDCInterfaceInfo->Config.DataOUTEndpointNumber);
|
||||||
|
|
||||||
if (Endpoint_IsOUTReceived() && !(Endpoint_BytesInEndpoint()))
|
if (Endpoint_IsOUTReceived() && !(Endpoint_BytesInEndpoint()))
|
||||||
|
|
|
@ -36,17 +36,17 @@
|
||||||
|
|
||||||
#include "Benito.h"
|
#include "Benito.h"
|
||||||
|
|
||||||
/** Counter for the number of milliseconds remaining for the target /RESET pulse being generated. */
|
/** Circular buffer to hold data from the serial port before it is sent to the host. */
|
||||||
volatile uint8_t ResetPulseMSRemaining = 0;
|
RingBuff_t Tx_Buffer;
|
||||||
|
|
||||||
/** Counter for the number of milliseconds remaining for the TX activity LED pulse being generated. */
|
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
|
||||||
volatile uint8_t TxPulseMSRemaining = 0;
|
volatile struct
|
||||||
|
{
|
||||||
/** Counter for the number of milliseconds remaining for the RX activity LED pulse being generated. */
|
uint8_t ResetPulse; /**< Milliseconds remaining for target /RESET pulse */
|
||||||
volatile uint8_t RxPulseMSRemaining = 0;
|
uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
|
||||||
|
uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
|
||||||
/** Counter for the number of milliseconds remaining for the enumeration LED ping-pong being generated. */
|
uint8_t PingPongLEDPulse; /**< Milliseconds remaining for enumeration Tx/Rx ping-pong LED pulse */
|
||||||
volatile uint8_t PingPongMSRemaining = 0;
|
} PulseMSRemaining;
|
||||||
|
|
||||||
/** LUFA CDC Class driver interface configuration and state information. This structure is
|
/** LUFA CDC Class driver interface configuration and state information. This structure is
|
||||||
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
* passed to all CDC Class driver functions, so that multiple instances of the same class
|
||||||
|
@ -75,50 +75,52 @@ USB_ClassInfo_CDC_Device_t VirtualSerial_CDC_Interface =
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
SetupHardware();
|
SetupHardware();
|
||||||
|
|
||||||
|
Buffer_Initialize(&Tx_Buffer);
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Echo bytes from the host to the target via the hardware USART */
|
/* Echo bytes from the host to the target via the hardware USART */
|
||||||
if (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface) > 0)
|
while (CDC_Device_BytesReceived(&VirtualSerial_CDC_Interface) > 0)
|
||||||
{
|
{
|
||||||
Serial_TxByte(CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));
|
Serial_TxByte(CDC_Device_ReceiveByte(&VirtualSerial_CDC_Interface));
|
||||||
|
|
||||||
LEDs_TurnOnLEDs(LEDMASK_TX);
|
LEDs_TurnOnLEDs(LEDMASK_TX);
|
||||||
TxPulseMSRemaining = TX_RX_LED_PULSE_MS;
|
PulseMSRemaining.TxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Echo bytes from the target to the host via the virtual serial port */
|
/* Echo bytes from the target to the host via the virtual serial port */
|
||||||
if (Serial_IsCharReceived())
|
while (Tx_Buffer.Elements > 0)
|
||||||
{
|
{
|
||||||
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Serial_RxByte());
|
CDC_Device_SendByte(&VirtualSerial_CDC_Interface, Buffer_GetElement(&Tx_Buffer));
|
||||||
|
|
||||||
LEDs_TurnOnLEDs(LEDMASK_RX);
|
LEDs_TurnOnLEDs(LEDMASK_RX);
|
||||||
RxPulseMSRemaining = TX_RX_LED_PULSE_MS;
|
PulseMSRemaining.RxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the millisecond timer has elapsed */
|
/* Check if the millisecond timer has elapsed */
|
||||||
if (TIFR0 & (1 << OCF0A))
|
if (TIFR0 & (1 << OCF0A))
|
||||||
{
|
{
|
||||||
/* Check if the LEDs should be ping-ponging (during enumeration) */
|
|
||||||
if (PingPongMSRemaining && !(--PingPongMSRemaining))
|
|
||||||
{
|
|
||||||
LEDs_ToggleLEDs(LEDMASK_TX | LEDMASK_RX);
|
|
||||||
PingPongMSRemaining = PING_PONG_LED_PULSE_MS;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the reset pulse period has elapsed, if so tristate the target reset line */
|
/* Check if the reset pulse period has elapsed, if so tristate the target reset line */
|
||||||
if (ResetPulseMSRemaining && !(--ResetPulseMSRemaining))
|
if (PulseMSRemaining.ResetPulse && !(--PulseMSRemaining.ResetPulse))
|
||||||
{
|
{
|
||||||
LEDs_TurnOffLEDs(LEDMASK_BUSY);
|
LEDs_TurnOffLEDs(LEDMASK_BUSY);
|
||||||
AVR_RESET_LINE_DDR &= ~AVR_RESET_LINE_MASK;
|
AVR_RESET_LINE_DDR &= ~AVR_RESET_LINE_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if the LEDs should be ping-ponging (during enumeration) */
|
||||||
|
if (PulseMSRemaining.PingPongLEDPulse && !(--PulseMSRemaining.PingPongLEDPulse))
|
||||||
|
{
|
||||||
|
LEDs_ToggleLEDs(LEDMASK_TX | LEDMASK_RX);
|
||||||
|
PulseMSRemaining.PingPongLEDPulse = PING_PONG_LED_PULSE_MS;
|
||||||
|
}
|
||||||
|
|
||||||
/* Turn off TX LED(s) once the TX pulse period has elapsed */
|
/* Turn off TX LED(s) once the TX pulse period has elapsed */
|
||||||
if (TxPulseMSRemaining && !(--TxPulseMSRemaining))
|
if (PulseMSRemaining.TxLEDPulse && !(--PulseMSRemaining.TxLEDPulse))
|
||||||
LEDs_TurnOffLEDs(LEDMASK_TX);
|
LEDs_TurnOffLEDs(LEDMASK_TX);
|
||||||
|
|
||||||
/* Turn off RX LED(s) once the RX pulse period has elapsed */
|
/* Turn off RX LED(s) once the RX pulse period has elapsed */
|
||||||
if (RxPulseMSRemaining && !(--RxPulseMSRemaining))
|
if (PulseMSRemaining.RxLEDPulse && !(--PulseMSRemaining.RxLEDPulse))
|
||||||
LEDs_TurnOffLEDs(LEDMASK_RX);
|
LEDs_TurnOffLEDs(LEDMASK_RX);
|
||||||
|
|
||||||
/* Clear the millisecond timer CTC flag (cleared by writing logic one to the register) */
|
/* Clear the millisecond timer CTC flag (cleared by writing logic one to the register) */
|
||||||
|
@ -158,21 +160,21 @@ void SetupHardware(void)
|
||||||
/** Event handler for the library USB Connection event. */
|
/** Event handler for the library USB Connection event. */
|
||||||
void EVENT_USB_Device_Connect(void)
|
void EVENT_USB_Device_Connect(void)
|
||||||
{
|
{
|
||||||
PingPongMSRemaining = PING_PONG_LED_PULSE_MS;
|
PulseMSRemaining.PingPongLEDPulse = PING_PONG_LED_PULSE_MS;
|
||||||
LEDs_SetAllLEDs(LEDMASK_TX);
|
LEDs_SetAllLEDs(LEDMASK_TX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event handler for the library USB Disconnection event. */
|
/** Event handler for the library USB Disconnection event. */
|
||||||
void EVENT_USB_Device_Disconnect(void)
|
void EVENT_USB_Device_Disconnect(void)
|
||||||
{
|
{
|
||||||
PingPongMSRemaining = 0;
|
PulseMSRemaining.PingPongLEDPulse = 0;
|
||||||
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Event handler for the library USB Configuration Changed event. */
|
/** Event handler for the library USB Configuration Changed event. */
|
||||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||||
{
|
{
|
||||||
PingPongMSRemaining = 0;
|
PulseMSRemaining.PingPongLEDPulse = 0;
|
||||||
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
LEDs_SetAllLEDs(LEDS_NO_LEDS);
|
||||||
|
|
||||||
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
|
if (!(CDC_Device_ConfigureEndpoints(&VirtualSerial_CDC_Interface)))
|
||||||
|
@ -220,11 +222,22 @@ void EVENT_CDC_Device_LineEncodingChanged(USB_ClassInfo_CDC_Device_t* const CDCI
|
||||||
}
|
}
|
||||||
|
|
||||||
UCSR1A = (1 << U2X1);
|
UCSR1A = (1 << U2X1);
|
||||||
UCSR1B = ((1 << TXEN1) | (1 << RXEN1));
|
UCSR1B = ((1 << RXCIE1) | (1 << TXEN1) | (1 << RXEN1));
|
||||||
UCSR1C = ConfigMask;
|
UCSR1C = ConfigMask;
|
||||||
UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
|
UBRR1 = SERIAL_2X_UBBRVAL((uint16_t)CDCInterfaceInfo->State.LineEncoding.BaudRateBPS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ISR to manage the reception of data from the serial port, placing received bytes into a circular buffer
|
||||||
|
* for later transmission to the host.
|
||||||
|
*/
|
||||||
|
ISR(USART1_RX_vect, ISR_BLOCK)
|
||||||
|
{
|
||||||
|
uint8_t ReceivedByte = UDR1;
|
||||||
|
|
||||||
|
if (USB_DeviceState == DEVICE_STATE_Configured)
|
||||||
|
Buffer_StoreElement(&Tx_Buffer, ReceivedByte);
|
||||||
|
}
|
||||||
|
|
||||||
/** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event.
|
/** Event handler for the CDC Class driver Host-to-Device Line Encoding Changed event.
|
||||||
*
|
*
|
||||||
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
|
* \param[in] CDCInterfaceInfo Pointer to the CDC class interface configuration structure being referenced
|
||||||
|
@ -236,7 +249,7 @@ void EVENT_CDC_Device_ControLineStateChanged(USB_ClassInfo_CDC_Device_t* const C
|
||||||
{
|
{
|
||||||
LEDs_SetAllLEDs(LEDMASK_BUSY);
|
LEDs_SetAllLEDs(LEDMASK_BUSY);
|
||||||
|
|
||||||
AVR_RESET_LINE_DDR |= AVR_RESET_LINE_MASK;
|
AVR_RESET_LINE_DDR |= AVR_RESET_LINE_MASK;
|
||||||
ResetPulseMSRemaining = AVR_RESET_PULSE_MS;
|
PulseMSRemaining.ResetPulse = AVR_RESET_PULSE_MS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include <avr/power.h>
|
#include <avr/power.h>
|
||||||
|
|
||||||
#include "Descriptors.h"
|
#include "Descriptors.h"
|
||||||
|
#include "Lib/RingBuff.h"
|
||||||
|
|
||||||
#include <LUFA/Version.h>
|
#include <LUFA/Version.h>
|
||||||
#include <LUFA/Drivers/Board/LEDs.h>
|
#include <LUFA/Drivers/Board/LEDs.h>
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
LUFA Library
|
||||||
|
Copyright (C) Dean Camera, 2009.
|
||||||
|
|
||||||
|
dean [at] fourwalledcubicle [dot] com
|
||||||
|
www.fourwalledcubicle.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software
|
||||||
|
and its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name of the author not be used in
|
||||||
|
advertising or publicity pertaining to distribution of the
|
||||||
|
software without specific, written prior permission.
|
||||||
|
|
||||||
|
The author disclaim all warranties with regard to this
|
||||||
|
software, including all implied warranties of merchantability
|
||||||
|
and fitness. In no event shall the author be liable for any
|
||||||
|
special, indirect or consequential damages or any damages
|
||||||
|
whatsoever resulting from loss of use, data or profits, whether
|
||||||
|
in an action of contract, negligence or other tortious action,
|
||||||
|
arising out of or in connection with the use or performance of
|
||||||
|
this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "RingBuff.h"
|
||||||
|
|
||||||
|
void Buffer_Initialize(RingBuff_t* Buffer)
|
||||||
|
{
|
||||||
|
BUFF_ATOMIC_BLOCK
|
||||||
|
{
|
||||||
|
Buffer->InPtr = (RingBuff_Data_t*)&Buffer->Buffer;
|
||||||
|
Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;
|
||||||
|
Buffer->Elements = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Buffer_StoreElement(RingBuff_t* Buffer, RingBuff_Data_t Data)
|
||||||
|
{
|
||||||
|
BUFF_ATOMIC_BLOCK
|
||||||
|
{
|
||||||
|
#if defined(BUFF_DROPOLD)
|
||||||
|
if (Buffer->Elements == BUFF_LENGTH)
|
||||||
|
{
|
||||||
|
Buffer->OutPtr++;
|
||||||
|
|
||||||
|
if (Buffer->OutPtr == &Buffer->Buffer[BUFF_LENGTH])
|
||||||
|
Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Buffer->Elements++;
|
||||||
|
}
|
||||||
|
#elif defined(BUFF_DROPNEW)
|
||||||
|
if (Buffer->Elements == BUFF_LENGTH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Buffer->Elements++;
|
||||||
|
#elif defined(BUFF_NODROPCHECK)
|
||||||
|
Buffer->Elements++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
*(Buffer->InPtr) = Data;
|
||||||
|
Buffer->InPtr++;
|
||||||
|
|
||||||
|
if (Buffer->InPtr == &Buffer->Buffer[BUFF_LENGTH])
|
||||||
|
Buffer->InPtr = (RingBuff_Data_t*)&Buffer->Buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RingBuff_Data_t Buffer_GetElement(RingBuff_t* Buffer)
|
||||||
|
{
|
||||||
|
RingBuff_Data_t BuffData;
|
||||||
|
|
||||||
|
BUFF_ATOMIC_BLOCK
|
||||||
|
{
|
||||||
|
#if defined(BUFF_EMPTYRETURNSZERO)
|
||||||
|
if (!(Buffer->Elements))
|
||||||
|
return 0;
|
||||||
|
#elif !defined(BUFF_NOEMPTYCHECK)
|
||||||
|
#error No empty buffer check behaviour specified.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BuffData = *(Buffer->OutPtr);
|
||||||
|
|
||||||
|
Buffer->OutPtr++;
|
||||||
|
Buffer->Elements--;
|
||||||
|
|
||||||
|
if (Buffer->OutPtr == &Buffer->Buffer[BUFF_LENGTH])
|
||||||
|
Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return BuffData;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BUFF_USEPEEK)
|
||||||
|
RingBuff_Data_t Buffer_PeekElement(const RingBuff_t* Buffer)
|
||||||
|
{
|
||||||
|
RingBuff_Data_t BuffData;
|
||||||
|
|
||||||
|
BUFF_ATOMIC_BLOCK
|
||||||
|
{
|
||||||
|
#if defined(BUFF_EMPTYRETURNSZERO)
|
||||||
|
if (!(Buffer->Elements))
|
||||||
|
return 0;
|
||||||
|
#elif !defined(BUFF_NOEMPTYCHECK)
|
||||||
|
#error No empty buffer check behaviour specified.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BuffData = *(Buffer->OutPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BuffData;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
LUFA Library
|
||||||
|
Copyright (C) Dean Camera, 2009.
|
||||||
|
|
||||||
|
dean [at] fourwalledcubicle [dot] com
|
||||||
|
www.fourwalledcubicle.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software
|
||||||
|
and its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name of the author not be used in
|
||||||
|
advertising or publicity pertaining to distribution of the
|
||||||
|
software without specific, written prior permission.
|
||||||
|
|
||||||
|
The author disclaim all warranties with regard to this
|
||||||
|
software, including all implied warranties of merchantability
|
||||||
|
and fitness. In no event shall the author be liable for any
|
||||||
|
special, indirect or consequential damages or any damages
|
||||||
|
whatsoever resulting from loss of use, data or profits, whether
|
||||||
|
in an action of contract, negligence or other tortious action,
|
||||||
|
arising out of or in connection with the use or performance of
|
||||||
|
this software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Buffer Configuration: */
|
||||||
|
/* Buffer length - select static size of created ring buffers: */
|
||||||
|
#define BUFF_STATICSIZE 128 // Set to the static ring buffer size for all ring buffers (place size after define)
|
||||||
|
|
||||||
|
/* Volatile mode - uncomment to make buffers volatile, for use in ISRs, etc: */
|
||||||
|
#define BUFF_VOLATILE // Uncomment to cause all ring buffers to become volatile (and atomic if multi-byte) in access
|
||||||
|
|
||||||
|
/* Drop mode - select behaviour when Buffer_StoreElement called on a full buffer: */
|
||||||
|
#define BUFF_DROPOLD // Uncomment to cause full ring buffers to drop the oldest character to make space when full
|
||||||
|
// #define BUFF_DROPNEW // Uncomment to cause full ring buffers to drop the new character when full
|
||||||
|
// #define BUFF_NODROPCHECK // Uncomment to ignore full ring buffer checks - checking left to user!
|
||||||
|
|
||||||
|
/* Underflow behaviour - select behaviour when Buffer_GetElement is called with an empty ring buffer: */
|
||||||
|
//#define BUFF_EMPTYRETURNSZERO // Uncomment to return 0 when an empty ring buffer is read
|
||||||
|
#define BUFF_NOEMPTYCHECK // Uncomment to disable checking of empty ring buffers - checking left to user!
|
||||||
|
|
||||||
|
/* Buffer storage type - set the datatype for the stored data */
|
||||||
|
#define BUFF_DATATYPE uint8_t // Change to the data type that is going to be stored into the buffer
|
||||||
|
|
||||||
|
/* Peek routine - uncomment to include the peek routine (fetches next byte without removing it from the buffer */
|
||||||
|
//#define BUFF_USEPEEK
|
||||||
|
|
||||||
|
#ifndef _RINGBUFF_H_
|
||||||
|
#define _RINGBUFF_H_
|
||||||
|
|
||||||
|
/* Includes: */
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/atomic.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <LUFA/Common/Common.h>
|
||||||
|
|
||||||
|
/* Defines and checks: */
|
||||||
|
#if defined(BUFF_STATICSIZE)
|
||||||
|
#define BUFF_LENGTH BUFF_STATICSIZE
|
||||||
|
#else
|
||||||
|
#error No buffer length specified!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !(defined(BUFF_DROPOLD) || defined(BUFF_DROPNEW) || defined(BUFF_NODROPCHECK))
|
||||||
|
#error No buffer drop mode specified.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BUFF_DATATYPE)
|
||||||
|
#error Ringbuffer storage data type not specified.
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(BUFF_VOLATILE)
|
||||||
|
#define BUFF_MODE volatile
|
||||||
|
#define BUFF_ATOMIC_BLOCK ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
|
||||||
|
#else
|
||||||
|
#define BUFF_MODE
|
||||||
|
#define BUFF_ATOMIC_BLOCK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (BUFF_STATICSIZE > LONG_MAX)
|
||||||
|
#define RingBuff_Elements_t uint64_t
|
||||||
|
#elif (BUFF_STATICSIZE > INT_MAX)
|
||||||
|
#define RingBuff_Elements_t uint32_t
|
||||||
|
#elif (BUFF_STATICSIZE > CHAR_MAX)
|
||||||
|
#define RingBuff_Elements_t uint16_t
|
||||||
|
#else
|
||||||
|
#define RingBuff_Elements_t uint8_t
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Type Defines: */
|
||||||
|
typedef BUFF_DATATYPE RingBuff_Data_t;
|
||||||
|
|
||||||
|
typedef BUFF_MODE struct
|
||||||
|
{
|
||||||
|
RingBuff_Data_t Buffer[BUFF_LENGTH];
|
||||||
|
RingBuff_Data_t* InPtr;
|
||||||
|
RingBuff_Data_t* OutPtr;
|
||||||
|
RingBuff_Elements_t Elements;
|
||||||
|
} RingBuff_t;
|
||||||
|
|
||||||
|
/* Function Prototypes: */
|
||||||
|
void Buffer_Initialize(RingBuff_t* Buff);
|
||||||
|
void Buffer_StoreElement(RingBuff_t* Buffer, RingBuff_Data_t Data);
|
||||||
|
RingBuff_Data_t Buffer_GetElement(RingBuff_t* Buffer);
|
||||||
|
#if defined(BUFF_USEPEEK)
|
||||||
|
RingBuff_Data_t Buffer_PeekElement(const RingBuff_t* Buffer);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -134,6 +134,7 @@ LUFA_OPTS += -D USE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENAB
|
||||||
# List C source files here. (C dependencies are automatically generated.)
|
# List C source files here. (C dependencies are automatically generated.)
|
||||||
SRC = $(TARGET).c \
|
SRC = $(TARGET).c \
|
||||||
Descriptors.c \
|
Descriptors.c \
|
||||||
|
Lib/RingBuff.c \
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
|
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c \
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
|
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c \
|
||||||
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
|
$(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Host.c \
|
||||||
|
@ -192,9 +193,9 @@ CSTANDARD = -std=gnu99
|
||||||
|
|
||||||
# Place -D or -U options here for C sources
|
# Place -D or -U options here for C sources
|
||||||
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS)
|
CDEFS = -DF_CPU=$(F_CPU)UL -DF_CLOCK=$(F_CLOCK)UL -DBOARD=BOARD_$(BOARD) $(LUFA_OPTS)
|
||||||
CDEFS += -DAVR_RESET_LINE_PORT="PORTB"
|
CDEFS += -DAVR_RESET_LINE_PORT="PORTD"
|
||||||
CDEFS += -DAVR_RESET_LINE_DDR="DDRB"
|
CDEFS += -DAVR_RESET_LINE_DDR="DDRD"
|
||||||
CDEFS += -DAVR_RESET_LINE_MASK="(1 << 0)"
|
CDEFS += -DAVR_RESET_LINE_MASK="(1 << 4)"
|
||||||
CDEFS += -DAVR_RESET_PULSE_MS=10
|
CDEFS += -DAVR_RESET_PULSE_MS=10
|
||||||
CDEFS += -DTX_RX_LED_PULSE_MS=30
|
CDEFS += -DTX_RX_LED_PULSE_MS=30
|
||||||
CDEFS += -DPING_PONG_LED_PULSE_MS=100
|
CDEFS += -DPING_PONG_LED_PULSE_MS=100
|
||||||
|
|
|
@ -34,10 +34,11 @@
|
||||||
* the project and is responsible for the initial application hardware configuration.
|
* the project and is responsible for the initial application hardware configuration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TODO: Add reversed target connector checks
|
// TODO: Fix PROGRAM FLASH and PROGRAM EEPROM command processing
|
||||||
// TODO: Add in software SPI for lower programming speeds below 125KHz
|
// TODO: Add in software SPI for lower programming speeds below 125KHz
|
||||||
// TODO: Add in VTARGET detection
|
// TODO: Add in VTARGET detection
|
||||||
// TODO: Add in software SPI for lower programming speeds
|
// TODO: Add reversed target connector checks
|
||||||
|
// TODO: Add Doxygen comments to functions
|
||||||
|
|
||||||
#include "AVRISP.h"
|
#include "AVRISP.h"
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
|
|
||||||
#include <LUFA/Version.h>
|
#include <LUFA/Version.h>
|
||||||
#include <LUFA/Drivers/Board/LEDs.h>
|
#include <LUFA/Drivers/Board/LEDs.h>
|
||||||
#include <LUFA/Drivers/Peripheral/SPI.h>
|
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
#include <LUFA/Drivers/USB/USB.h>
|
||||||
|
|
||||||
#include "Lib/V2Protocol.h"
|
#include "Lib/V2Protocol.h"
|
||||||
|
|
|
@ -38,13 +38,15 @@
|
||||||
|
|
||||||
/* Includes: */
|
/* Includes: */
|
||||||
#include <LUFA/Drivers/USB/USB.h>
|
#include <LUFA/Drivers/USB/USB.h>
|
||||||
|
#include <LUFA/Drivers/Peripheral/SPI.h>
|
||||||
|
|
||||||
#include "../Descriptors.h"
|
#include "../Descriptors.h"
|
||||||
#include "V2ProtocolConstants.h"
|
#include "V2ProtocolConstants.h"
|
||||||
#include "V2ProtocolParams.h"
|
#include "V2ProtocolParams.h"
|
||||||
#include "V2ProtocolTarget.h"
|
#include "V2ProtocolTarget.h"
|
||||||
|
|
||||||
/* Macros: */
|
/* Macros: */
|
||||||
|
/** Programmer ID string, returned to the host during the CMD_SIGN_ON command processing */
|
||||||
#define PROGRAMMER_ID "AVRISP_MK2"
|
#define PROGRAMMER_ID "AVRISP_MK2"
|
||||||
|
|
||||||
#define READ_WRITE_HIGH_BYTE_MASK (1 << 3)
|
#define READ_WRITE_HIGH_BYTE_MASK (1 << 3)
|
||||||
|
|
|
@ -67,7 +67,7 @@ static ParameterItem_t ParameterTable[] =
|
||||||
.ParamPrivellages = PARAM_PRIV_READ },
|
.ParamPrivellages = PARAM_PRIV_READ },
|
||||||
|
|
||||||
{ .ParamID = PARAM_SCK_DURATION,
|
{ .ParamID = PARAM_SCK_DURATION,
|
||||||
.ParamValue = 0x06,
|
.ParamValue = (TOTAL_PROGRAMMING_SPEEDS - 1),
|
||||||
.ParamPrivellages = PARAM_PRIV_READ | PARAM_PRIV_WRITE },
|
.ParamPrivellages = PARAM_PRIV_READ | PARAM_PRIV_WRITE },
|
||||||
|
|
||||||
{ .ParamID = PARAM_RESET_POLARITY,
|
{ .ParamID = PARAM_RESET_POLARITY,
|
||||||
|
|
|
@ -46,15 +46,19 @@
|
||||||
#include "V2ProtocolConstants.h"
|
#include "V2ProtocolConstants.h"
|
||||||
|
|
||||||
/* Macros: */
|
/* Macros: */
|
||||||
|
/* Parameter privellage mask to allow the host PC to read the parameter's value */
|
||||||
#define PARAM_PRIV_READ (1 << 0)
|
#define PARAM_PRIV_READ (1 << 0)
|
||||||
|
|
||||||
|
/* Parameter privellage mask to allow the host PC to change the parameter's value */
|
||||||
#define PARAM_PRIV_WRITE (1 << 1)
|
#define PARAM_PRIV_WRITE (1 << 1)
|
||||||
|
|
||||||
/* Type Defines: */
|
/* Type Defines: */
|
||||||
|
/** Type define for a parameter table entry indicating a PC readable or writable device parameter. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
const uint8_t ParamID;
|
const uint8_t ParamID; /**< Parameter ID number to uniquely identify the parameter within the device */
|
||||||
uint8_t ParamValue;
|
uint8_t ParamValue; /**< Current parameter's value within the device */
|
||||||
uint8_t ParamPrivellages;
|
uint8_t ParamPrivellages; /**< Parameter privellages to allow the host to read or write the parameter's value */
|
||||||
} ParameterItem_t;
|
} ParameterItem_t;
|
||||||
|
|
||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
|
|
|
@ -40,7 +40,7 @@ uint32_t CurrentAddress;
|
||||||
|
|
||||||
uint8_t V2Protocol_GetSPIPrescalerMask(void)
|
uint8_t V2Protocol_GetSPIPrescalerMask(void)
|
||||||
{
|
{
|
||||||
static const uint8_t SPIMaskFromSCKDuration[] =
|
static const uint8_t SPIMaskFromSCKDuration[TOTAL_PROGRAMMING_SPEEDS] =
|
||||||
{
|
{
|
||||||
#if (F_CPU == 8000000)
|
#if (F_CPU == 8000000)
|
||||||
SPI_SPEED_FCPU_DIV_2,
|
SPI_SPEED_FCPU_DIV_2,
|
||||||
|
@ -76,12 +76,6 @@ void V2Protocol_ChangeTargetResetLine(bool ResetTarget)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void V2Protocol_DelayMS(uint8_t MS)
|
|
||||||
{
|
|
||||||
TCNT0 = 0;
|
|
||||||
while (TCNT0 < MS);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAddress, uint8_t PollValue,
|
uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAddress, uint8_t PollValue,
|
||||||
uint8_t DelayMS, uint8_t ReadMemCommand)
|
uint8_t DelayMS, uint8_t ReadMemCommand)
|
||||||
{
|
{
|
||||||
|
@ -96,7 +90,7 @@ uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAdd
|
||||||
break;
|
break;
|
||||||
case PROG_MODE_WORD_VALUE_MASK:
|
case PROG_MODE_WORD_VALUE_MASK:
|
||||||
case PROG_MODE_PAGED_VALUE_MASK:
|
case PROG_MODE_PAGED_VALUE_MASK:
|
||||||
TCNT0 = 0;
|
TCNT0 = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -121,7 +115,7 @@ uint8_t V2Protocol_WaitForProgComplete(uint8_t ProgrammingMode, uint16_t PollAdd
|
||||||
|
|
||||||
uint8_t V2Protocol_WaitWhileTargetBusy(void)
|
uint8_t V2Protocol_WaitWhileTargetBusy(void)
|
||||||
{
|
{
|
||||||
TCNT0 = 0;
|
TCNT0 = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
|
|
@ -48,11 +48,22 @@
|
||||||
#include "V2ProtocolParams.h"
|
#include "V2ProtocolParams.h"
|
||||||
|
|
||||||
/* Macros: */
|
/* Macros: */
|
||||||
|
/** Total number of allowable ISP programming speeds supported by the device */
|
||||||
|
#define TOTAL_PROGRAMMING_SPEEDS 7
|
||||||
|
|
||||||
|
/** Timeout in milliseconds of target busy-wait loops waiting for a command to complete */
|
||||||
#define TARGET_BUSY_TIMEOUT_MS 150
|
#define TARGET_BUSY_TIMEOUT_MS 150
|
||||||
|
|
||||||
/* External Variables: */
|
/* External Variables: */
|
||||||
extern uint32_t CurrentAddress;
|
extern uint32_t CurrentAddress;
|
||||||
|
|
||||||
|
/* Inline Functions: */
|
||||||
|
static inline void V2Protocol_DelayMS(uint8_t MS)
|
||||||
|
{
|
||||||
|
TCNT0 = 0;
|
||||||
|
while (TCNT0 < MS);
|
||||||
|
}
|
||||||
|
|
||||||
/* Function Prototypes: */
|
/* Function Prototypes: */
|
||||||
uint8_t V2Protocol_GetSPIPrescalerMask(void);
|
uint8_t V2Protocol_GetSPIPrescalerMask(void);
|
||||||
void V2Protocol_ChangeTargetResetLine(bool ResetTarget);
|
void V2Protocol_ChangeTargetResetLine(bool ResetTarget);
|
||||||
|
|
Loading…
Reference in New Issue