Commit b243c2b8 authored by Dean Camera's avatar Dean Camera
Browse files

Magstripe Project: Ensure that empty tracks still print out a newline...

Magstripe Project: Ensure that empty tracks still print out a newline seperator so that the host always knows what track data is being sent.

Updates to PrinterHost demo to include some PCL test data plus fixes to the GetDeviceID routine.
parent d6543dee
......@@ -32,7 +32,8 @@
uint8_t Printer_GetDeviceID(Device_ID_String_t* DeviceIDString)
{
uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
uint8_t ErrorCode = HOST_SENDCONTROL_Successful;
uint16_t DeviceIDStringLength;
USB_ControlRequest = (USB_Request_Header_t)
{
......@@ -40,19 +41,24 @@ uint8_t Printer_GetDeviceID(Device_ID_String_t* DeviceIDString)
bRequest: GET_DEVICE_ID,
wValue: 0,
wIndex: 0,
wLength: sizeof(DeviceIDString),
wLength: sizeof(DeviceIDString->Length),
};
if ((ErrorCode == USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
DeviceIDString->Length = SwapEndian_16(DeviceIDString->Length);
DeviceIDStringLength = SwapEndian_16(DeviceIDString->Length);
/* Protect against overflow for the null terminator if the string length is equal to or larger than the buffer */
if (DeviceIDString->Length >= sizeof(DeviceIDString->String))
DeviceIDString->Length = sizeof(DeviceIDString->String) - 1;
if (DeviceIDStringLength >= sizeof(DeviceIDString->String))
DeviceIDStringLength = sizeof(DeviceIDString->String) - 1;
USB_ControlRequest.wLength = DeviceIDStringLength;
if ((ErrorCode = USB_Host_SendControlRequest(DeviceIDString)) != HOST_SENDCONTROL_Successful)
return ErrorCode;
DeviceIDString->String[DeviceIDString->Length] = 0x00;
DeviceIDString->String[DeviceIDStringLength] = 0x00;
return HOST_SENDCONTROL_Successful;
}
......
......@@ -130,7 +130,7 @@ void USB_Printer_Host(void)
printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
......@@ -144,7 +144,7 @@ void USB_Printer_Host(void)
printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
......@@ -154,23 +154,18 @@ void USB_Printer_Host(void)
USB_HostState = HOST_STATE_Configured;
break;
case HOST_STATE_Configured:
puts_P(PSTR("Printer Enumerated.\r\n"));
USB_HostState = HOST_STATE_Ready;
break;
case HOST_STATE_Ready:
/* Indicate device busy via the status LEDs */
LEDs_SetAllLEDs(LEDS_LED3 | LEDS_LED4);
printf_P(PSTR("Printer Protocol: %d\r\n"), PrinterProtocol);
puts_P(PSTR("Retrieving Device ID...\r\n"));
Device_ID_String_t DeviceIDString;
if (Printer_GetDeviceID(&DeviceIDString) != HOST_SENDCONTROL_Successful)
if ((ErrorCode = Printer_GetDeviceID(&DeviceIDString)) != HOST_SENDCONTROL_Successful)
{
puts_P(PSTR("Control Error (Get DeviceID).\r\n"));
printf_P(PSTR(" -- Error Code: %d\r\n"), ErrorCode);
/* Indicate error via status LEDs */
LEDs_SetAllLEDs(LEDS_LED1);
LEDs_SetAllLEDs(LEDMASK_USB_ERROR);
/* Wait until USB device disconnected */
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
......@@ -178,9 +173,42 @@ void USB_Printer_Host(void)
}
printf_P(PSTR("Printer Device ID: %s\r\n"), DeviceIDString.String);
puts_P(PSTR("Printer Enumerated.\r\n"));
USB_HostState = HOST_STATE_Ready;
break;
case HOST_STATE_Ready:
/* Indicate device busy via the status LEDs */
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
//--------------------------------------------------------------
#define TEST_TEXT_PAGE "\033%-12345X\033E LUFA PCL Test Page \033E\033%-12345X"
Pipe_SelectPipe(PRINTER_DATA_OUT_PIPE);
Pipe_Unfreeze();
puts_P(PSTR("Waiting for Printer to Become Ready...\r\n"));
while (!(Pipe_IsReadWriteAllowed()));
uint8_t strSize = sizeof(TEST_TEXT_PAGE)-1;
printf_P(PSTR("Printer Write Allowed, sending complete page (%d bytes)...\r\n"), strSize);
Pipe_Write_Stream_LE(TEST_TEXT_PAGE, strSize);
Pipe_ClearOUT();
puts_P(PSTR("Page sent to printer.\r\n"));
while (!(Pipe_IsReadWriteAllowed()));
Pipe_Freeze();
puts_P(PSTR("Pipe Frozen.\r\n"));
//--------------------------------------------------------------
/* Indicate device no longer busy */
LEDs_SetAllLEDs(LEDS_LED4);
LEDs_SetAllLEDs(LEDMASK_USB_READY);
USB_HostState = HOST_STATE_WaitForDeviceRemoval;
break;
......
......@@ -60,6 +60,9 @@
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
#define LEDMASK_USB_BUSY (LEDS_LED2)
/* External Variables: */
extern uint8_t PrinterProtocol;
......
......@@ -60,7 +60,7 @@
# MCU name
MCU = at90usb1287
MCU = at90usb647
# Target board (see library "Board Types" documentation, USER or blank for projects not requiring
......
......@@ -40,7 +40,10 @@
/** Bit buffers to hold the read bits for each of the three magnetic card tracks before they are transmitted
* to the host as keyboard presses.
*/
BitBuffer_t TrackDataBuffers[3];
BitBuffer_t TrackDataBuffers[TOTAL_TRACKS];
/** Pointer to the current track buffer being sent to the host. */
BitBuffer_t* CurrentTrackBuffer = &TrackDataBuffers[TOTAL_TRACKS];
/** LUFA HID Class driver interface configuration and state information. This structure is
* passed to all HID Class driver functions, so that multiple instances of the same class
......@@ -71,7 +74,7 @@ int main(void)
{
SetupHardware();
for (uint8_t Buffer = 0; Buffer < 3; Buffer++)
for (uint8_t Buffer = 0; Buffer < TOTAL_TRACKS; Buffer++)
BitBuffer_Init(&TrackDataBuffers[Buffer]);
for (;;)
......@@ -124,13 +127,13 @@ void ReadMagstripeData(void)
while (Magstripe_LCL & MAG_CARDPRESENT)
{
for (uint8_t Track = 0; Track < 3; Track++)
for (uint8_t Track = 0; Track < TOTAL_TRACKS; Track++)
{
bool DataPinLevel = ((Magstripe_LCL & TrackInfo[Track].DataMask) != 0);
bool ClockPinLevel = ((Magstripe_LCL & TrackInfo[Track].ClockMask) != 0);
bool ClockLevelChanged = (((Magstripe_LCL ^ Magstripe_Prev) & TrackInfo[Track].ClockMask) != 0);
/* Sample on rising clock edges */
/* Sample data on rising clock edges from the card reader */
if (ClockPinLevel && ClockLevelChanged)
BitBuffer_StoreNextBit(&TrackDataBuffers[Track], DataPinLevel);
}
......@@ -138,6 +141,8 @@ void ReadMagstripeData(void)
Magstripe_Prev = Magstripe_LCL;
Magstripe_LCL = Magstripe_GetStatus();
}
CurrentTrackBuffer = &TrackDataBuffers[0];
}
/** Event handler for the library USB Configuration Changed event. */
......@@ -169,41 +174,28 @@ ISR(TIMER0_COMPA_vect, ISR_BLOCK)
*/
uint16_t CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDInterfaceInfo, uint8_t* const ReportID, void* ReportData)
{
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
static bool IsKeyReleaseReport;
static bool IsNewlineReport;
USB_KeyboardReport_Data_t* KeyboardReport = (USB_KeyboardReport_Data_t*)ReportData;
BitBuffer_t* Buffer = NULL;
/* Key reports must be interleaved with key release reports, or repeated keys will be ignored */
IsKeyReleaseReport = !IsKeyReleaseReport;
IsKeyReleaseReport = !IsKeyReleaseReport;
if (IsKeyReleaseReport)
if ((IsKeyReleaseReport) || (CurrentTrackBuffer == &TrackDataBuffers[TOTAL_TRACKS]))
{
/* No more data to send, or key release report between key presses */
KeyboardReport->KeyCode = KEY_NONE;
}
else if (IsNewlineReport)
else if (!(CurrentTrackBuffer->Elements))
{
IsNewlineReport = false;
/* End of current track, send an enter press and change to the next track's buffer */
KeyboardReport->KeyCode = KEY_ENTER;
CurrentTrackBuffer++;
}
else
{
/* Read out tracks in ascending order - when each track buffer is empty, progress to next buffer */
if (TrackDataBuffers[0].Elements)
Buffer = &TrackDataBuffers[0];
else if (TrackDataBuffers[1].Elements)
Buffer = &TrackDataBuffers[1];
else if (TrackDataBuffers[2].Elements)
Buffer = &TrackDataBuffers[2];
else
return 0;
KeyboardReport->KeyCode = BitBuffer_GetNextBit(Buffer) ? KEY_1 : KEY_0;
/* If current track buffer now empty, next report must be a newline to seperate track data */
if (!(Buffer->Elements))
IsNewlineReport = true;
/* Still data in the current track; convert next bit to a 1 or 0 keypress */
KeyboardReport->KeyCode = BitBuffer_GetNextBit(CurrentTrackBuffer) ? KEY_1 : KEY_0;
}
return sizeof(USB_KeyboardReport_Data_t);
......
......@@ -51,6 +51,9 @@
#include <LUFA/Drivers/USB/Class/HID.h>
/* Macros: */
/** Total number of tracks which can be read from the card, between 1 and 3. */
#define TOTAL_TRACKS 3
/** HID keyboard keycode to indicate that no is currently pressed. */
#define KEY_NONE 0
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment