build without eclipse :)

This commit is contained in:
Pavol Rusnak 2011-04-02 00:01:07 +02:00
parent c3ff2207cd
commit 8b871d5d47
50 changed files with 143 additions and 2514 deletions

166
firmware/src/DiskImg.c Normal file
View file

@ -0,0 +1,166 @@
/* Disk Image */
#include "memory.h"
const unsigned char DiskImage[MSC_ImageSize] = {
0xEB,0x3C,0x90,0x4D,0x53,0x44,0x4F,0x53,0x35,0x2E,0x30,0x00,0x02,0x01,0x01,0x00,
0x01,0x10,0x00,0x20,0x00,0xF8,0x02,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x29,0x74,0x19,0x02,0x27,0x4C,0x50,0x43,0x32,0x33,
0x36,0x38,0x20,0x55,0x53,0x42,0x46,0x41,0x54,0x31,0x32,0x20,0x20,0x20,0x33,0xC9,
0x8E,0xD1,0xBC,0xF0,0x7B,0x8E,0xD9,0xB8,0x00,0x20,0x8E,0xC0,0xFC,0xBD,0x00,0x7C,
0x38,0x4E,0x24,0x7D,0x24,0x8B,0xC1,0x99,0xE8,0x3C,0x01,0x72,0x1C,0x83,0xEB,0x3A,
0x66,0xA1,0x1C,0x7C,0x26,0x66,0x3B,0x07,0x26,0x8A,0x57,0xFC,0x75,0x06,0x80,0xCA,
0x02,0x88,0x56,0x02,0x80,0xC3,0x10,0x73,0xEB,0x33,0xC9,0x8A,0x46,0x10,0x98,0xF7,
0x66,0x16,0x03,0x46,0x1C,0x13,0x56,0x1E,0x03,0x46,0x0E,0x13,0xD1,0x8B,0x76,0x11,
0x60,0x89,0x46,0xFC,0x89,0x56,0xFE,0xB8,0x20,0x00,0xF7,0xE6,0x8B,0x5E,0x0B,0x03,
0xC3,0x48,0xF7,0xF3,0x01,0x46,0xFC,0x11,0x4E,0xFE,0x61,0xBF,0x00,0x00,0xE8,0xE6,
0x00,0x72,0x39,0x26,0x38,0x2D,0x74,0x17,0x60,0xB1,0x0B,0xBE,0xA1,0x7D,0xF3,0xA6,
0x61,0x74,0x32,0x4E,0x74,0x09,0x83,0xC7,0x20,0x3B,0xFB,0x72,0xE6,0xEB,0xDC,0xA0,
0xFB,0x7D,0xB4,0x7D,0x8B,0xF0,0xAC,0x98,0x40,0x74,0x0C,0x48,0x74,0x13,0xB4,0x0E,
0xBB,0x07,0x00,0xCD,0x10,0xEB,0xEF,0xA0,0xFD,0x7D,0xEB,0xE6,0xA0,0xFC,0x7D,0xEB,
0xE1,0xCD,0x16,0xCD,0x19,0x26,0x8B,0x55,0x1A,0x52,0xB0,0x01,0xBB,0x00,0x00,0xE8,
0x3B,0x00,0x72,0xE8,0x5B,0x8A,0x56,0x24,0xBE,0x0B,0x7C,0x8B,0xFC,0xC7,0x46,0xF0,
0x3D,0x7D,0xC7,0x46,0xF4,0x29,0x7D,0x8C,0xD9,0x89,0x4E,0xF2,0x89,0x4E,0xF6,0xC6,
0x06,0x96,0x7D,0xCB,0xEA,0x03,0x00,0x00,0x20,0x0F,0xB6,0xC8,0x66,0x8B,0x46,0xF8,
0x66,0x03,0x46,0x1C,0x66,0x8B,0xD0,0x66,0xC1,0xEA,0x10,0xEB,0x5E,0x0F,0xB6,0xC8,
0x4A,0x4A,0x8A,0x46,0x0D,0x32,0xE4,0xF7,0xE2,0x03,0x46,0xFC,0x13,0x56,0xFE,0xEB,
0x4A,0x52,0x50,0x06,0x53,0x6A,0x01,0x6A,0x10,0x91,0x8B,0x46,0x18,0x96,0x92,0x33,
0xD2,0xF7,0xF6,0x91,0xF7,0xF6,0x42,0x87,0xCA,0xF7,0x76,0x1A,0x8A,0xF2,0x8A,0xE8,
0xC0,0xCC,0x02,0x0A,0xCC,0xB8,0x01,0x02,0x80,0x7E,0x02,0x0E,0x75,0x04,0xB4,0x42,
0x8B,0xF4,0x8A,0x56,0x24,0xCD,0x13,0x61,0x61,0x72,0x0B,0x40,0x75,0x01,0x42,0x03,
0x5E,0x0B,0x49,0x75,0x06,0xF8,0xC3,0x41,0xBB,0x00,0x00,0x60,0x66,0x6A,0x00,0xEB,
0xB0,0x4E,0x54,0x4C,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20,0x0D,0x0A,0x52,0x65,
0x6D,0x6F,0x76,0x65,0x20,0x64,0x69,0x73,0x6B,0x73,0x20,0x6F,0x72,0x20,0x6F,0x74,
0x68,0x65,0x72,0x20,0x6D,0x65,0x64,0x69,0x61,0x2E,0xFF,0x0D,0x0A,0x44,0x69,0x73,
0x6B,0x20,0x65,0x72,0x72,0x6F,0x72,0xFF,0x0D,0x0A,0x50,0x72,0x65,0x73,0x73,0x20,
0x61,0x6E,0x79,0x20,0x6B,0x65,0x79,0x20,0x74,0x6F,0x20,0x72,0x65,0x73,0x74,0x61,
0x72,0x74,0x0D,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xAC,0xCB,0xD8,0x55,0xAA,
0xF8,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x4C,0x50,0x43,0x31,0x33,0x34,0x78,0x20,0x55,0x53,0x42,0x28,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x52,0x45,0x41,0x44,0x4D,0x45,0x20,0x20,0x54,0x58,0x54,0x21,0x00,0x00,0x00,0x00,
0x21,0x00,0xBB,0x32,0x00,0x00,0xDC,0x83,0xBB,0x32,0x02,0x00,0x5D,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x54,0x68,0x69,0x73,0x20,0x69,0x73,0x20,0x61,0x20,0x55,0x53,0x42,0x20,0x4D,0x65,
0x6D,0x6F,0x72,0x79,0x20,0x44,0x65,0x76,0x69,0x63,0x65,0x20,0x64,0x65,0x6D,0x6F,
0x6E,0x73,0x74,0x72,0x61,0x74,0x69,0x6F,0x6E,0x20,0x66,0x6F,0x72,0x0D,0x0A,0x74,
0x68,0x65,0x20,0x4E,0x58,0x50,0x20,0x20,0x4E,0x58,0x50,0x31,0x33,0x58,0x58,0x20,
0x42,0x6F,0x61,0x72,0x64,0x20,0x77,0x69,0x74,0x68,0x20,0x4E,0x58,0x50,0x20,0x4C,
0x50,0x43,0x31,0x33,0x34,0x33,0x2E,0x20,0x20,0x20,0x20,0x0D,0x0A,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

360
firmware/src/cdcuser.c Normal file
View file

@ -0,0 +1,360 @@
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: cdcuser.c
* Purpose: USB Communication Device Class User module
* Version: V1.10
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include "type.h"
#include "usb.h"
#include "usbhw.h"
#include "usbcfg.h"
#include "usbcore.h"
#include "cdc.h"
#include "cdcuser.h"
#include "serial.h"
unsigned char BulkBufIn [USB_CDC_BUFSIZE]; // Buffer to store USB IN packet
unsigned char BulkBufOut [USB_CDC_BUFSIZE]; // Buffer to store USB OUT packet
unsigned char NotificationBuf [10];
CDC_LINE_CODING CDC_LineCoding = {9600, 0, 0, 8};
unsigned short CDC_SerialState = 0x0000;
unsigned short CDC_DepInEmpty = 1; // Data IN EP is empty
/*----------------------------------------------------------------------------
We need a buffer for incomming data on USB port because USB receives
much faster than UART transmits
*---------------------------------------------------------------------------*/
/* Buffer masks */
#define CDC_BUF_SIZE (64) // Output buffer in bytes (power 2)
// large enough for file transfer
#define CDC_BUF_MASK (CDC_BUF_SIZE-1ul)
/* Buffer read / write macros */
#define CDC_BUF_RESET(cdcBuf) (cdcBuf.rdIdx = cdcBuf.wrIdx = 0)
#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn))
#define CDC_BUF_RD(cdcBuf) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++])
#define CDC_BUF_EMPTY(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx)
#define CDC_BUF_FULL(cdcBuf) (cdcBuf.rdIdx == cdcBuf.wrIdx+1)
#define CDC_BUF_COUNT(cdcBuf) (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx))
// CDC output buffer
typedef struct __CDC_BUF_T {
unsigned char data[CDC_BUF_SIZE];
unsigned int wrIdx;
unsigned int rdIdx;
} CDC_BUF_T;
CDC_BUF_T CDC_OutBuf; // buffer for all CDC Out data
/*----------------------------------------------------------------------------
read data from CDC_OutBuf
*---------------------------------------------------------------------------*/
int CDC_RdOutBuf (char *buffer, const int *length) {
int bytesToRead, bytesRead;
/* Read *length bytes, block if *bytes are not avaialable */
bytesToRead = *length;
bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
bytesRead = bytesToRead;
// ... add code to check for underrun
while (bytesToRead--) {
*buffer++ = CDC_BUF_RD(CDC_OutBuf);
}
return (bytesRead);
}
/*----------------------------------------------------------------------------
write data to CDC_OutBuf
*---------------------------------------------------------------------------*/
int CDC_WrOutBuf (const char *buffer, int *length) {
int bytesToWrite, bytesWritten;
// Write *length bytes
bytesToWrite = *length;
bytesWritten = bytesToWrite;
// ... add code to check for overwrite
while (bytesToWrite) {
CDC_BUF_WR(CDC_OutBuf, *buffer++); // Copy Data to buffer
bytesToWrite--;
}
return (bytesWritten);
}
/*----------------------------------------------------------------------------
check if character(s) are available at CDC_OutBuf
*---------------------------------------------------------------------------*/
int CDC_OutBufAvailChar (int *availChar) {
*availChar = CDC_BUF_COUNT(CDC_OutBuf);
return (0);
}
/* end Buffer handling */
/*----------------------------------------------------------------------------
CDC Initialisation
Initializes the data structures and serial port
Parameters: None
Return Value: None
*---------------------------------------------------------------------------*/
void CDC_Init (void) {
ser_OpenPort ();
ser_InitPort (CDC_LineCoding.dwDTERate,
CDC_LineCoding.bDataBits,
CDC_LineCoding.bParityType,
CDC_LineCoding.bCharFormat);
CDC_DepInEmpty = 1;
CDC_SerialState = CDC_GetSerialState();
CDC_BUF_RESET(CDC_OutBuf);
}
/*----------------------------------------------------------------------------
CDC SendEncapsulatedCommand Request Callback
Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request
Parameters: None (global SetupPacket and EP0Buf)
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_SendEncapsulatedCommand (void) {
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC GetEncapsulatedResponse Request Callback
Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request
Parameters: None (global SetupPacket and EP0Buf)
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_GetEncapsulatedResponse (void) {
/* ... add code to handle request */
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC SetCommFeature Request Callback
Called automatically on CDC Set_COMM_FATURE Request
Parameters: FeatureSelector
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector) {
/* ... add code to handle request */
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC GetCommFeature Request Callback
Called automatically on CDC Get_COMM_FATURE Request
Parameters: FeatureSelector
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector) {
/* ... add code to handle request */
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC ClearCommFeature Request Callback
Called automatically on CDC CLEAR_COMM_FATURE Request
Parameters: FeatureSelector
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector) {
/* ... add code to handle request */
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC SetLineCoding Request Callback
Called automatically on CDC SET_LINE_CODING Request
Parameters: none (global SetupPacket and EP0Buf)
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_SetLineCoding (void) {
CDC_LineCoding.dwDTERate = (EP0Buf[0] << 0)
| (EP0Buf[1] << 8)
| (EP0Buf[2] << 16)
| (EP0Buf[3] << 24);
CDC_LineCoding.bCharFormat = EP0Buf[4];
CDC_LineCoding.bParityType = EP0Buf[5];
CDC_LineCoding.bDataBits = EP0Buf[6];
ser_ClosePort();
ser_OpenPort ();
ser_InitPort (CDC_LineCoding.dwDTERate,
CDC_LineCoding.bDataBits,
CDC_LineCoding.bParityType,
CDC_LineCoding.bCharFormat);
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC GetLineCoding Request Callback
Called automatically on CDC GET_LINE_CODING Request
Parameters: None (global SetupPacket and EP0Buf)
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_GetLineCoding (void) {
EP0Buf[0] = (CDC_LineCoding.dwDTERate >> 0) & 0xFF;
EP0Buf[1] = (CDC_LineCoding.dwDTERate >> 8) & 0xFF;
EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF;
EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF;
EP0Buf[4] = CDC_LineCoding.bCharFormat;
EP0Buf[5] = CDC_LineCoding.bParityType;
EP0Buf[6] = CDC_LineCoding.bDataBits;
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC SetControlLineState Request Callback
Called automatically on CDC SET_CONTROL_LINE_STATE Request
Parameters: ControlSignalBitmap
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap) {
/* ... add code to handle request */
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC SendBreak Request Callback
Called automatically on CDC Set_COMM_FATURE Request
Parameters: 0xFFFF start of Break
0x0000 stop of Break
0x#### Duration of Break
Return Value: TRUE - Success, FALSE - Error
*---------------------------------------------------------------------------*/
uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {
/* ... add code to handle request */
return (TRUE);
}
/*----------------------------------------------------------------------------
CDC_BulkIn call on DataIn Request
Parameters: none
Return Value: none
*---------------------------------------------------------------------------*/
void CDC_BulkIn(void) {
int numBytesRead, numBytesAvail;
ser_AvailChar (&numBytesAvail);
// ... add code to check for overwrite
numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail);
// send over USB
if (numBytesRead > 0) {
USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);
}
else {
CDC_DepInEmpty = 1;
}
}
/*----------------------------------------------------------------------------
CDC_BulkOut call on DataOut Request
Parameters: none
Return Value: none
*---------------------------------------------------------------------------*/
void CDC_BulkOut(void) {
int numBytesRead;
// get data from USB into intermediate buffer
numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]);
// ... add code to check for overwrite
// store data in a buffer to transmit it over serial interface
CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead);
}
/*----------------------------------------------------------------------------
Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.
Parameters: none
Return Value: SerialState as defined in usbcdc11.pdf
*---------------------------------------------------------------------------*/
unsigned short CDC_GetSerialState (void) {
unsigned short temp;
CDC_SerialState = 0;
ser_LineState (&temp);
if (temp & 0x8000) CDC_SerialState |= CDC_SERIAL_STATE_RX_CARRIER;
if (temp & 0x2000) CDC_SerialState |= CDC_SERIAL_STATE_TX_CARRIER;
if (temp & 0x0010) CDC_SerialState |= CDC_SERIAL_STATE_BREAK;
if (temp & 0x4000) CDC_SerialState |= CDC_SERIAL_STATE_RING;
if (temp & 0x0008) CDC_SerialState |= CDC_SERIAL_STATE_FRAMING;
if (temp & 0x0004) CDC_SerialState |= CDC_SERIAL_STATE_PARITY;
if (temp & 0x0002) CDC_SerialState |= CDC_SERIAL_STATE_OVERRUN;
return (CDC_SerialState);
}
/*----------------------------------------------------------------------------
Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.
*---------------------------------------------------------------------------*/
void CDC_NotificationIn (void) {
NotificationBuf[0] = 0xA1; // bmRequestType
NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE; // bNotification (SERIAL_STATE)
NotificationBuf[2] = 0x00; // wValue
NotificationBuf[3] = 0x00;
NotificationBuf[4] = 0x00; // wIndex (Interface #, LSB first)
NotificationBuf[5] = 0x00;
NotificationBuf[6] = 0x02; // wLength (Data length = 2 bytes, LSB first)
NotificationBuf[7] = 0x00;
NotificationBuf[8] = (CDC_SerialState >> 0) & 0xFF; // UART State Bitmap (16bits, LSB first)
NotificationBuf[9] = (CDC_SerialState >> 8) & 0xFF;
USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10); // send notification
}

60
firmware/src/clkconfig.c Normal file
View file

@ -0,0 +1,60 @@
/******************************************************************************
* clkconfig.c: clock configuration C file for NXP LPC13xx Family
* Microprocessors
*
* Copyright(C) 2009, NXP Semiconductor
* All rights reserved.
*
* History
* 2009.08.20 ver 1.00 Preliminary version, first Release
*
******************************************************************************/
#include "LPC13xx.h"
#include "clkconfig.h"
/*****************************************************************************
** Function name: WDT_CLK_Setup
**
** Descriptions: Configure WDT clock.
** parameters: clock source: irc_osc(0), main_clk(1), wdt_osc(2).
**
** Returned value: None
**
*****************************************************************************/
void WDT_CLK_Setup ( uint32_t clksrc )
{
/* Watchdog configuration. */
/* Freq = 0.5Mhz, div_sel is 0, divided by 2. WDT_OSC should be 250khz */
LPC_SYSCON->WDTOSCCTRL = (0x1<<5)|0x00;
LPC_SYSCON->WDTCLKSEL = clksrc; /* Select clock source */
LPC_SYSCON->WDTCLKUEN = 0x01; /* Update clock */
LPC_SYSCON->WDTCLKUEN = 0x00; /* Toggle update register once */
LPC_SYSCON->WDTCLKUEN = 0x01;
while ( !(LPC_SYSCON->WDTCLKUEN & 0x01) ); /* Wait until updated */
LPC_SYSCON->WDTCLKDIV = 1; /* Divided by 1 */
LPC_SYSCON->PDRUNCFG &= ~(0x1<<6); /* Let WDT clock run */
return;
}
/*****************************************************************************
** Function name: CLKOUT_Setup
**
** Descriptions: Configure CLKOUT for reference clock check.
** parameters: clock source: irc_osc(0), sys_osc(1), wdt_osc(2),
** main_clk(3).
**
** Returned value: None
**
*****************************************************************************/
void CLKOUT_Setup ( uint32_t clksrc )
{
/* debug PLL after configuration. */
LPC_SYSCON->CLKOUTCLKSEL = clksrc; /* Select Main clock */
LPC_SYSCON->CLKOUTUEN = 0x01; /* Update clock */
LPC_SYSCON->CLKOUTUEN = 0x00; /* Toggle update register once */
LPC_SYSCON->CLKOUTUEN = 0x01;
while ( !(LPC_SYSCON->CLKOUTUEN & 0x01) ); /* Wait until updated */
LPC_SYSCON->CLKOUTDIV = 1; /* Divided by 1 */
return;
}

784
firmware/src/core_cm3.c Normal file
View file

@ -0,0 +1,784 @@
/**************************************************************************//**
* @file core_cm3.c
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Source File
* @version V1.30
* @date 30. October 2009
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#include <stdint.h>
/* define compiler specific symbols */
#if defined ( __CC_ARM )
#define __ASM __asm /*!< asm keyword for ARM Compiler */
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
#elif defined ( __ICCARM__ )
#define __ASM __asm /*!< asm keyword for IAR Compiler */
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only avaiable in High optimization mode! */
#elif defined ( __GNUC__ )
#define __ASM __asm /*!< asm keyword for GNU Compiler */
#define __INLINE inline /*!< inline keyword for GNU Compiler */
#elif defined ( __TASKING__ )
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
#endif
/* ################### Compiler specific Intrinsics ########################### */
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
/**
* @brief Return the Process Stack Pointer
*
* @return ProcessStackPointer
*
* Return the actual process stack pointer
*/
__ASM uint32_t __get_PSP(void)
{
mrs r0, psp
bx lr
}
/**
* @brief Set the Process Stack Pointer
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
__ASM void __set_PSP(uint32_t topOfProcStack)
{
msr psp, r0
bx lr
}
/**
* @brief Return the Main Stack Pointer
*
* @return Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
__ASM uint32_t __get_MSP(void)
{
mrs r0, msp
bx lr
}
/**
* @brief Set the Main Stack Pointer
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
__ASM void __set_MSP(uint32_t mainStackPointer)
{
msr msp, r0
bx lr
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in unsigned short value
*/
__ASM uint32_t __REV16(uint16_t value)
{
rev16 r0, r0
bx lr
}
/**
* @brief Reverse byte order in signed short value with sign extension to integer
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in signed short value with sign extension to integer
*/
__ASM int32_t __REVSH(int16_t value)
{
revsh r0, r0
bx lr
}
#if (__ARMCC_VERSION < 400000)
/**
* @brief Remove the exclusive lock created by ldrex
*
* Removes the exclusive lock which is created by ldrex.
*/
__ASM void __CLREX(void)
{
clrex
}
/**
* @brief Return the Base Priority value
*
* @return BasePriority
*
* Return the content of the base priority register
*/
__ASM uint32_t __get_BASEPRI(void)
{
mrs r0, basepri
bx lr
}
/**
* @brief Set the Base Priority value
*
* @param basePri BasePriority
*
* Set the base priority register
*/
__ASM void __set_BASEPRI(uint32_t basePri)
{
msr basepri, r0
bx lr
}
/**
* @brief Return the Priority Mask value
*
* @return PriMask
*
* Return state of the priority mask bit from the priority mask register
*/
__ASM uint32_t __get_PRIMASK(void)
{
mrs r0, primask
bx lr
}
/**
* @brief Set the Priority Mask value
*
* @param priMask PriMask
*
* Set the priority mask bit in the priority mask register
*/
__ASM void __set_PRIMASK(uint32_t priMask)
{
msr primask, r0
bx lr
}
/**
* @brief Return the Fault Mask value
*
* @return FaultMask
*
* Return the content of the fault mask register
*/
__ASM uint32_t __get_FAULTMASK(void)
{
mrs r0, faultmask
bx lr
}
/**
* @brief Set the Fault Mask value
*
* @param faultMask faultMask value
*
* Set the fault mask register
*/
__ASM void __set_FAULTMASK(uint32_t faultMask)
{
msr faultmask, r0
bx lr
}
/**
* @brief Return the Control Register value
*
* @return Control value
*
* Return the content of the control register
*/
__ASM uint32_t __get_CONTROL(void)
{
mrs r0, control
bx lr
}
/**
* @brief Set the Control Register value
*
* @param control Control value
*
* Set the control register
*/
__ASM void __set_CONTROL(uint32_t control)
{
msr control, r0
bx lr
}
#endif /* __ARMCC_VERSION */
#elif (defined (__ICCARM__)) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#pragma diag_suppress=Pe940
/**
* @brief Return the Process Stack Pointer
*
* @return ProcessStackPointer
*
* Return the actual process stack pointer
*/
uint32_t __get_PSP(void)
{
__ASM("mrs r0, psp");
__ASM("bx lr");
}
/**
* @brief Set the Process Stack Pointer
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack)
{
__ASM("msr psp, r0");
__ASM("bx lr");
}
/**
* @brief Return the Main Stack Pointer
*
* @return Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
uint32_t __get_MSP(void)
{
__ASM("mrs r0, msp");
__ASM("bx lr");
}
/**
* @brief Set the Main Stack Pointer
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack)
{
__ASM("msr msp, r0");
__ASM("bx lr");
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in unsigned short value
*/
uint32_t __REV16(uint16_t value)
{
__ASM("rev16 r0, r0");
__ASM("bx lr");
}
/**
* @brief Reverse bit order of value
*
* @param value value to reverse
* @return reversed value
*
* Reverse bit order of value
*/
uint32_t __RBIT(uint32_t value)
{
__ASM("rbit r0, r0");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive (8 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 8 bit values)
*/
uint8_t __LDREXB(uint8_t *addr)
{
__ASM("ldrexb r0, [r0]");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive (16 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 16 bit values
*/
uint16_t __LDREXH(uint16_t *addr)
{
__ASM("ldrexh r0, [r0]");
__ASM("bx lr");
}
/**
* @brief LDR Exclusive (32 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 32 bit values
*/
uint32_t __LDREXW(uint32_t *addr)
{
__ASM("ldrex r0, [r0]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive (8 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 8 bit values
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
__ASM("strexb r0, r0, [r1]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive (16 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 16 bit values
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
__ASM("strexh r0, r0, [r1]");
__ASM("bx lr");
}
/**
* @brief STR Exclusive (32 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 32 bit values
*/
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
__ASM("strex r0, r0, [r1]");
__ASM("bx lr");
}
#pragma diag_default=Pe940
#elif (defined (__GNUC__)) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/**
* @brief Return the Process Stack Pointer
*
* @return ProcessStackPointer
*
* Return the actual process stack pointer
*/
uint32_t __get_PSP(void) __attribute__( ( naked ) );
uint32_t __get_PSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, psp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
}
/**
* @brief Set the Process Stack Pointer
*
* @param topOfProcStack Process Stack Pointer
*
* Assign the value ProcessStackPointer to the MSP
* (process stack pointer) Cortex processor register
*/
void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) );
void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n\t"
"BX lr \n\t" : : "r" (topOfProcStack) );
}
/**
* @brief Return the Main Stack Pointer
*
* @return Main Stack Pointer
*
* Return the current value of the MSP (main stack pointer)
* Cortex processor register
*/
uint32_t __get_MSP(void) __attribute__( ( naked ) );
uint32_t __get_MSP(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, msp\n\t"
"MOV r0, %0 \n\t"
"BX lr \n\t" : "=r" (result) );
return(result);
}
/**
* @brief Set the Main Stack Pointer
*
* @param topOfMainStack Main Stack Pointer
*
* Assign the value mainStackPointer to the MSP
* (main stack pointer) Cortex processor register
*/
void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) );
void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n\t"
"BX lr \n\t" : : "r" (topOfMainStack) );
}
/**
* @brief Return the Base Priority value
*
* @return BasePriority
*
* Return the content of the base priority register
*/
uint32_t __get_BASEPRI(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/**
* @brief Set the Base Priority value
*
* @param basePri BasePriority
*
* Set the base priority register
*/
void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/**
* @brief Return the Priority Mask value
*
* @return PriMask
*
* Return state of the priority mask bit from the priority mask register
*/
uint32_t __get_PRIMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/**
* @brief Set the Priority Mask value
*
* @param priMask PriMask
*
* Set the priority mask bit in the priority mask register
*/
void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
/**
* @brief Return the Fault Mask value
*
* @return FaultMask
*
* Return the content of the fault mask register
*/
uint32_t __get_FAULTMASK(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/**
* @brief Set the Fault Mask value
*
* @param faultMask faultMask value
*
* Set the fault mask register
*/
void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
/**
* @brief Return the Control Register value
*
* @return Control value
*
* Return the content of the control register
*/
uint32_t __get_CONTROL(void)
{
uint32_t result=0;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/**
* @brief Set the Control Register value
*
* @param control Control value
*
* Set the control register
*/
void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/**
* @brief Reverse byte order in integer value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in integer value
*/
uint32_t __REV(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse byte order in unsigned short value
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in unsigned short value
*/
uint32_t __REV16(uint16_t value)
{
uint32_t result=0;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse byte order in signed short value with sign extension to integer
*
* @param value value to reverse
* @return reversed value
*
* Reverse byte order in signed short value with sign extension to integer
*/
int32_t __REVSH(int16_t value)
{
uint32_t result=0;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief Reverse bit order of value
*
* @param value value to reverse
* @return reversed value
*
* Reverse bit order of value
*/
uint32_t __RBIT(uint32_t value)
{
uint32_t result=0;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/**
* @brief LDR Exclusive (8 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 8 bit value
*/
uint8_t __LDREXB(uint8_t *addr)
{
uint8_t result=0;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief LDR Exclusive (16 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 16 bit values
*/
uint16_t __LDREXH(uint16_t *addr)
{
uint16_t result=0;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief LDR Exclusive (32 bit)
*
* @param *addr address pointer
* @return value of (*address)
*
* Exclusive LDR command for 32 bit values
*/
uint32_t __LDREXW(uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/**
* @brief STR Exclusive (8 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 8 bit values
*/
uint32_t __STREXB(uint8_t value, uint8_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive (16 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 16 bit values
*/
uint32_t __STREXH(uint16_t value, uint16_t *addr)
{
uint32_t result=0;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/**
* @brief STR Exclusive (32 bit)
*
* @param value value to store
* @param *addr address pointer
* @return successful / failed
*
* Exclusive STR command for 32 bit values
*/
uint32_t __STREXW(uint32_t value, uint32_t *addr)
{
uint32_t result=0;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
#elif (defined (__TASKING__)) /*------------------ TASKING Compiler ---------------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif

View file

@ -0,0 +1,359 @@
//*****************************************************************************
// +--+
// | ++----+
// +-++ |
// | |
// +-+--+ |
// | +--+--+
// +----+ Copyright (c) 2009 Code Red Technologies Ltd.
//
// Microcontroller Startup code for use with Red Suite
//
// Software License Agreement
//
// The software is owned by Code Red Technologies and/or its suppliers, and is
// protected under applicable copyright laws. All rights are reserved. Any
// use in violation of the foregoing restrictions may subject the user to criminal
// sanctions under applicable laws, as well as to civil liability for the breach
// of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// USE OF THIS SOFTWARE FOR COMMERCIAL DEVELOPMENT AND/OR EDUCATION IS SUBJECT
// TO A CURRENT END USER LICENSE AGREEMENT (COMMERCIAL OR EDUCATIONAL) WITH
// CODE RED TECHNOLOGIES LTD.
//
//*****************************************************************************
#define WEAK __attribute__ ((weak))
#define ALIAS(f) __attribute__ ((weak, alias (#f)))
// Code Red - if CMSIS is being used, then SystemInit() routine
// will be called by startup code rather than in application's main()
#ifdef __USE_CMSIS
#include "system_LPC13xx.h"
#endif
//*****************************************************************************
//
// Forward declaration of the default handlers. These are aliased.
// When the application defines a handler (with the same name), this will
// automatically take precedence over these weak definitions
//
//*****************************************************************************
void Reset_Handler(void);
void ResetISR(void) ALIAS(Reset_Handler);
WEAK void NMI_Handler(void);
WEAK void HardFault_Handler(void);
WEAK void MemManage_Handler(void);
WEAK void BusFault_Handler(void);
WEAK void UsageFault_Handler(void);
WEAK void SVCall_Handler(void);
WEAK void DebugMon_Handler(void);
WEAK void PendSV_Handler(void);
WEAK void SysTick_Handler(void);
//*****************************************************************************
//
// Forward declaration of the specific IRQ handlers. These are aliased
// to the IntDefaultHandler, which is a 'forever' loop. When the application
// defines a handler (with the same name), this will automatically take
// precedence over these weak definitions
//
//*****************************************************************************
void I2C_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER16_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_0_IRQHandler (void) ALIAS(IntDefaultHandler);
void TIMER32_1_IRQHandler (void) ALIAS(IntDefaultHandler);
void SSP_IRQHandler (void) ALIAS(IntDefaultHandler);
void UART_IRQHandler (void) ALIAS(IntDefaultHandler);
void USB_IRQHandler (void) ALIAS(IntDefaultHandler);
void USB_FIQHandler (void) ALIAS(IntDefaultHandler);
void ADC_IRQHandler (void) ALIAS(IntDefaultHandler);
void WDT_IRQHandler (void) ALIAS(IntDefaultHandler);
void BOD_IRQHandler (void) ALIAS(IntDefaultHandler);
void FMC_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT3_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT2_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT1_IRQHandler (void) ALIAS(IntDefaultHandler);
void PIOINT0_IRQHandler (void) ALIAS(IntDefaultHandler);
void WAKEUP_IRQHandler (void) ALIAS(IntDefaultHandler);
//*****************************************************************************
//
// The entry point for the application.
// __main() is the entry point for redlib based applications
// main() is the entry point for newlib based applications
//
//*****************************************************************************
extern WEAK void __main(void);
extern WEAK void main(void);
//*****************************************************************************
//
// External declaration for the pointer to the stack top from the Linker Script
//
//*****************************************************************************
extern void _vStackTop;
//*****************************************************************************
//
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000.
//
//*****************************************************************************
__attribute__ ((section(".isr_vector")))
void (* const g_pfnVectors[])(void) =
{
// Core Level - CM3
(void *)&_vStackTop, // The initial stack pointer
Reset_Handler, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
SVCall_Handler, // SVCall handler
DebugMon_Handler, // Debug monitor handler
0, // Reserved
PendSV_Handler, // The PendSV handler
SysTick_Handler, // The SysTick handler
// Wakeup sources (40 ea.) for the I/O pins:
// PIO0 (0:11)
// PIO1 (0:11)
// PIO2 (0:11)
// PIO3 (0:3)
WAKEUP_IRQHandler, // PIO0_0 Wakeup
WAKEUP_IRQHandler, // PIO0_1 Wakeup
WAKEUP_IRQHandler, // PIO0_2 Wakeup
WAKEUP_IRQHandler, // PIO0_3 Wakeup
WAKEUP_IRQHandler, // PIO0_4 Wakeup
WAKEUP_IRQHandler, // PIO0_5 Wakeup
WAKEUP_IRQHandler, // PIO0_6 Wakeup
WAKEUP_IRQHandler, // PIO0_7 Wakeup
WAKEUP_IRQHandler, // PIO0_8 Wakeup
WAKEUP_IRQHandler, // PIO0_9 Wakeup
WAKEUP_IRQHandler, // PIO0_10 Wakeup
WAKEUP_IRQHandler, // PIO0_11 Wakeup
WAKEUP_IRQHandler, // PIO1_0 Wakeup
WAKEUP_IRQHandler, // PIO1_1 Wakeup
WAKEUP_IRQHandler, // PIO1_2 Wakeup
WAKEUP_IRQHandler, // PIO1_3 Wakeup
WAKEUP_IRQHandler, // PIO1_4 Wakeup
WAKEUP_IRQHandler, // PIO1_5 Wakeup
WAKEUP_IRQHandler, // PIO1_6 Wakeup
WAKEUP_IRQHandler, // PIO1_7 Wakeup
WAKEUP_IRQHandler, // PIO1_8 Wakeup
WAKEUP_IRQHandler, // PIO1_9 Wakeup
WAKEUP_IRQHandler, // PIO1_10 Wakeup
WAKEUP_IRQHandler, // PIO1_11 Wakeup
WAKEUP_IRQHandler, // PIO2_0 Wakeup
WAKEUP_IRQHandler, // PIO2_1 Wakeup
WAKEUP_IRQHandler, // PIO2_2 Wakeup
WAKEUP_IRQHandler, // PIO2_3 Wakeup
WAKEUP_IRQHandler, // PIO2_4 Wakeup
WAKEUP_IRQHandler, // PIO2_5 Wakeup
WAKEUP_IRQHandler, // PIO2_6 Wakeup
WAKEUP_IRQHandler, // PIO2_7 Wakeup
WAKEUP_IRQHandler, // PIO2_8 Wakeup
WAKEUP_IRQHandler, // PIO2_9 Wakeup
WAKEUP_IRQHandler, // PIO2_10 Wakeup
WAKEUP_IRQHandler, // PIO2_11 Wakeup
WAKEUP_IRQHandler, // PIO3_0 Wakeup
WAKEUP_IRQHandler, // PIO3_1 Wakeup
WAKEUP_IRQHandler, // PIO3_2 Wakeup
WAKEUP_IRQHandler, // PIO3_3 Wakeup
I2C_IRQHandler, // I2C0
TIMER16_0_IRQHandler, // CT16B0 (16-bit Timer 0)
TIMER16_1_IRQHandler, // CT16B1 (16-bit Timer 1)
TIMER32_0_IRQHandler, // CT32B0 (32-bit Timer 0)
TIMER32_1_IRQHandler, // CT32B1 (32-bit Timer 1)
SSP_IRQHandler, // SSP0
UART_IRQHandler, // UART0
USB_IRQHandler, // USB IRQ
USB_FIQHandler, // USB FIQ
ADC_IRQHandler, // ADC (A/D Converter)
WDT_IRQHandler, // WDT (Watchdog Timer)
BOD_IRQHandler, // BOD (Brownout Detect)
FMC_IRQHandler, // Flash (IP2111 Flash Memory Controller)
PIOINT3_IRQHandler, // PIO INT3
PIOINT2_IRQHandler, // PIO INT2
PIOINT1_IRQHandler, // PIO INT1
PIOINT0_IRQHandler, // PIO INT0
};
//*****************************************************************************
//
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory. The initializers for the
// for the "data" segment resides immediately following the "text" segment.
//
//*****************************************************************************
extern unsigned long _etext;
extern unsigned long _data;
extern unsigned long _edata;
extern unsigned long _bss;
extern unsigned long _ebss;
//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event. Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called. Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//
//*****************************************************************************
void
//ResetISR(void)
Reset_Handler(void)
{
unsigned long *pulSrc, *pulDest;
//
// Copy the data segment initializers from flash to SRAM.
//
pulSrc = &_etext;
for(pulDest = &_data; pulDest < &_edata; )
{
*pulDest++ = *pulSrc++;
}
//
// Zero fill the bss segment. This is done with inline assembly since this
// will clear the value of pulDest if it is not kept in a register.
//
__asm(" ldr r0, =_bss\n"
" ldr r1, =_ebss\n"
" mov r2, #0\n"
" .thumb_func\n"
"zero_loop:\n"
" cmp r0, r1\n"
" it lt\n"
" strlt r2, [r0], #4\n"
" blt zero_loop");
#ifdef __USE_CMSIS
SystemInit();
#endif
//
// Call the application's entry point.
// __main() is the entry point for redlib based applications (which calls main())
// main() is the entry point for newlib based applications
//
if (__main)
__main() ;
else
main() ;
//
// main() shouldn't return, but if it does, we'll just enter an infinite loop
//
while (1) {
;
}
}
//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI. This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
void NMI_Handler(void)
{
while(1)
{
}
}
void HardFault_Handler(void)
{
while(1)
{
}
}
void MemManage_Handler(void)
{
while(1)
{
}
}
void BusFault_Handler(void)
{
while(1)
{
}
}
void UsageFault_Handler(void)
{
while(1)
{
}
}
void SVCall_Handler(void)
{
while(1)
{
}
}
void DebugMon_Handler(void)
{
while(1)
{
}
}
void PendSV_Handler(void)
{
while(1)
{
}
}
void SysTick_Handler(void)
{
while(1)
{
}
}
//*****************************************************************************
//
// Processor ends up here if an unexpected interrupt occurs or a handler
// is not present in the application code.
//
//*****************************************************************************
static void IntDefaultHandler(void)
{
//
// Go into an infinite loop.
//
while(1)
{
}
}

119
firmware/src/edubrm.c Normal file
View file

@ -0,0 +1,119 @@
#include "LPC13xx.h"
#include "type.h"
#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "cdc.h"
#include "cdcuser.h"
#include "serial.h"
#include "vcomdemo.h"
#include "mscuser.h"
#include "memory.h"
#include "stdio.h"
#include "string.h"
#include "edubrm.h"
#define mainLED_BIT ( 7 )
void VCOM_Brm2Usb(void) {
/*
static char serBuf [USB_CDC_BUFSIZE];
int numBytesRead, numAvailByte;
serBuf[0] = 'A';
numBytesRead = 1;
/* ser_AvailChar (&numAvailByte);
if (numAvailByte > 0) {
if (CDC_DepInEmpty) {
numBytesRead = ser_Read (&serBuf[0], &numAvailByte);
CDC_DepInEmpty = 0;
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&serBuf[0], numBytesRead);
}
/*
}
*/
}
static char cmdInbuffer[256];
int cmdInbufferIndex = 0;
int checkForCommand(void) {
int i=0;
for (i=0;i<cmdInbufferIndex;i++) {
if (cmdInbuffer[i] == '\n' ) {
return i;
}
}
return 0;
}
static unsigned long ulLEDState = 1;
void enableLED() {
LPC_GPIO0->DIR |= ( 0x1 << mainLED_BIT );
}
void disableLED() {
LPC_GPIO0->DIR |= ( 0x0 << mainLED_BIT );
}
void toggleLED( ){
ulLEDState = !ulLEDState;
LPC_GPIO0->MASKED_ACCESS[ ( 1 << mainLED_BIT) ] = ( ulLEDState << mainLED_BIT );
}
void sendToUSB(char *string) {
USB_WriteEP (CDC_DEP_IN, string, strlen(string));
}
void commandReceived(char * receivedCommand) {
if (strcmp("PING", receivedCommand) == 0) {
//echo back
sendToUSB("PONG\n");
toggleLED();
} else if (strcmp("VERSION", receivedCommand) == 0) {
sendToUSB(VERSION);
toggleLED();
}
}
void VCOM_Usb2Brm(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;
int i=0;
static char receivedCommand[128];
CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);
for (i=0;i<numBytesRead;i++) { //TODO: replace with memcpy
cmdInbuffer[cmdInbufferIndex++] = serBuf[i];
}
int command = checkForCommand();
if (command != 0) {
//there is some command
cmdInbufferIndex = 0;
memset(receivedCommand,sizeof(receivedCommand), 0);
memcpy(receivedCommand, (unsigned char *)&cmdInbuffer[0], command);
//USB_WriteEP (CDC_DEP_IN, (unsigned char *)&cmdInbuffer[0], command);
commandReceived(receivedCommand);
}
}
}

6
firmware/src/edubrm.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef EDUBRM_H
#define EDUBRM_H
#define VERSION "0.0000001 pre-alpha\n"
#endif

708
firmware/src/mscuser.c Normal file
View file

@ -0,0 +1,708 @@
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: mscuser.c
* Purpose: Mass Storage Class Custom User Module
* Version: V1.20
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------
* History:
* V1.20 Added SCSI_READ12, SCSI_WRITE12
* V1.00 Initial Version
*---------------------------------------------------------------------------*/
#include "type.h"
#include "usb.h"
#include "msc.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "mscuser.h"
#include "memory.h"
uint8_t Memory[MSC_MemorySize]; /* MSC RAM */
uint32_t MemOK; /* Memory OK */
uint32_t Offset; /* R/W Offset */
uint32_t Length; /* R/W Length */
uint8_t BulkStage = MSC_BS_CBW; /* Bulk Stage */
uint8_t BulkBuf[MSC_MAX_PACKET] __attribute__ ((aligned (4))); /* Bulk In/Out Buffer */
uint8_t BulkLen; /* Bulk In/Out Length */
MSC_CBW CBW; /* Command Block Wrapper */
MSC_CSW CSW; /* Command Status Wrapper */
/*
* Set Stall for MSC Endpoint
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void MSC_SetStallEP (uint32_t EPNum) { /* set EP halt status according stall status */
USB_SetStallEP(EPNum);
USB_EndPointHalt |= (EPNum & 0x80) ? ((1 << 16) << (EPNum & 0x0F)) : (1 << EPNum);
}
/*
* MSC Mass Storage Reset Request Callback
* Called automatically on Mass Storage Reset Request
* Parameters: None (global SetupPacket and EP0Buf)
* Return Value: TRUE - Success, FALSE - Error
*/
uint32_t MSC_Reset (void) {
USB_EndPointStall = 0x00000000; /* EP must stay stalled */
CSW.dSignature = 0; /* invalid signature */
BulkStage = MSC_BS_CBW;
return (TRUE);
}
/*
* MSC Get Max LUN Request Callback
* Called automatically on Get Max LUN Request
* Parameters: None (global SetupPacket and EP0Buf)
* Return Value: TRUE - Success, FALSE - Error
*/
uint32_t MSC_GetMaxLUN (void) {
EP0Buf[0] = 0; /* No LUN associated with this device */
return (TRUE);
}
/*
* MSC Memory Read Callback
* Called automatically on Memory Read Event
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_MemoryRead (void) {
uint32_t n;
if (Length > MSC_MAX_PACKET) {
n = MSC_MAX_PACKET;
} else {
n = Length;
}
if ((Offset + n) > MSC_MemorySize) {
n = MSC_MemorySize - Offset;
BulkStage = MSC_BS_DATA_IN_LAST_STALL;
}
USB_WriteEP(MSC_EP_IN, &Memory[Offset], n);
Offset += n;
Length -= n;
CSW.dDataResidue -= n;
if (Length == 0) {
BulkStage = MSC_BS_DATA_IN_LAST;
}
if (BulkStage != MSC_BS_DATA_IN) {
CSW.bStatus = CSW_CMD_PASSED;
}
}
/*
* MSC Memory Write Callback
* Called automatically on Memory Write Event
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_MemoryWrite (void) {
uint32_t n;
if ((Offset + BulkLen) > MSC_MemorySize) {
BulkLen = MSC_MemorySize - Offset;
BulkStage = MSC_BS_CSW;
MSC_SetStallEP(MSC_EP_OUT);
}
for (n = 0; n < BulkLen; n++) {
Memory[Offset + n] = BulkBuf[n];
}
Offset += BulkLen;
Length -= BulkLen;
CSW.dDataResidue -= BulkLen;
if ((Length == 0) || (BulkStage == MSC_BS_CSW)) {
CSW.bStatus = CSW_CMD_PASSED;
MSC_SetCSW();
}
}
/*
* MSC Memory Verify Callback
* Called automatically on Memory Verify Event
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_MemoryVerify (void) {
uint32_t n;
if ((Offset + BulkLen) > MSC_MemorySize) {
BulkLen = MSC_MemorySize - Offset;
BulkStage = MSC_BS_CSW;
MSC_SetStallEP(MSC_EP_OUT);
}
for (n = 0; n < BulkLen; n++) {
if (Memory[Offset + n] != BulkBuf[n]) {
MemOK = FALSE;
break;
}
}
Offset += BulkLen;
Length -= BulkLen;
CSW.dDataResidue -= BulkLen;
if ((Length == 0) || (BulkStage == MSC_BS_CSW)) {
CSW.bStatus = (MemOK) ? CSW_CMD_PASSED : CSW_CMD_FAILED;
MSC_SetCSW();
}
}
/*
* MSC SCSI Read/Write Setup Callback
* Parameters: None (global variables)
* Return Value: TRUE - Success, FALSE - Error
*/
uint32_t MSC_RWSetup (void) {
uint32_t n;
/* Logical Block Address of First Block */
n = (CBW.CB[2] << 24) |
(CBW.CB[3] << 16) |
(CBW.CB[4] << 8) |
(CBW.CB[5] << 0);
Offset = n * MSC_BlockSize;
/* Number of Blocks to transfer */
switch (CBW.CB[0]) {
case SCSI_READ10:
case SCSI_WRITE10:
case SCSI_VERIFY10:
n = (CBW.CB[7] << 8) |
(CBW.CB[8] << 0);
break;
case SCSI_READ12:
case SCSI_WRITE12:
n = (CBW.CB[6] << 24) |
(CBW.CB[7] << 16) |
(CBW.CB[8] << 8) |
(CBW.CB[9] << 0);
break;
}
Length = n * MSC_BlockSize;
if (CBW.dDataLength == 0) { /* host requests no data */
CSW.bStatus = CSW_CMD_FAILED;
MSC_SetCSW();
return (FALSE);
}
if (CBW.dDataLength != Length) {
if ((CBW.bmFlags & 0x80) != 0) { /* stall appropriate EP */
MSC_SetStallEP(MSC_EP_IN);
} else {
MSC_SetStallEP(MSC_EP_OUT);
}
CSW.bStatus = CSW_CMD_FAILED;
MSC_SetCSW();
return (FALSE);
}
return (TRUE);
}
/*
* Check Data IN Format
* Parameters: None (global variables)
* Return Value: TRUE - Success, FALSE - Error
*/
uint32_t DataInFormat (void) {
if (CBW.dDataLength == 0) {
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
return (FALSE);
}
if ((CBW.bmFlags & 0x80) == 0) {
MSC_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
return (FALSE);
}
return (TRUE);
}
/*
* Perform Data IN Transfer
* Parameters: None (global variables)
* Return Value: TRUE - Success, FALSE - Error
*/
void DataInTransfer (void) {
if (BulkLen >= CBW.dDataLength)
BulkLen = CBW.dDataLength;
BulkStage = MSC_BS_DATA_IN_LAST;
USB_WriteEP(MSC_EP_IN, BulkBuf, BulkLen);
CSW.dDataResidue -= BulkLen;
CSW.bStatus = CSW_CMD_PASSED;
}
/*
* MSC SCSI Test Unit Ready Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_TestUnitReady (void) {
if (CBW.dDataLength != 0) {
if ((CBW.bmFlags & 0x80) != 0) {
MSC_SetStallEP(MSC_EP_IN);
} else {
MSC_SetStallEP(MSC_EP_OUT);
}
}
CSW.bStatus = CSW_CMD_PASSED;
MSC_SetCSW();
}
/*
* MSC SCSI Request Sense Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_RequestSense (void) {
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x70; /* Response Code */
BulkBuf[ 1] = 0x00;
BulkBuf[ 2] = 0x02; /* Sense Key */
BulkBuf[ 3] = 0x00;
BulkBuf[ 4] = 0x00;
BulkBuf[ 5] = 0x00;
BulkBuf[ 6] = 0x00;
BulkBuf[ 7] = 0x0A; /* Additional Length */
BulkBuf[ 8] = 0x00;
BulkBuf[ 9] = 0x00;
BulkBuf[10] = 0x00;
BulkBuf[11] = 0x00;
BulkBuf[12] = 0x30; /* ASC */
BulkBuf[13] = 0x01; /* ASCQ */
BulkBuf[14] = 0x00;
BulkBuf[15] = 0x00;
BulkBuf[16] = 0x00;
BulkBuf[17] = 0x00;
BulkLen = 18;
DataInTransfer();
}
/*
* MSC SCSI Inquiry Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_Inquiry (void) {
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x00; /* Direct Access Device */
BulkBuf[ 1] = 0x80; /* RMB = 1: Removable Medium */
BulkBuf[ 2] = 0x00; /* Version: No conformance claim to standard */
BulkBuf[ 3] = 0x01;
BulkBuf[ 4] = 36-4; /* Additional Length */
BulkBuf[ 5] = 0x80; /* SCCS = 1: Storage Controller Component */
BulkBuf[ 6] = 0x00;
BulkBuf[ 7] = 0x00;
BulkBuf[ 8] = 'K'; /* Vendor Identification */
BulkBuf[ 9] = 'e';
BulkBuf[10] = 'i';
BulkBuf[11] = 'l';
BulkBuf[12] = ' ';
BulkBuf[13] = ' ';
BulkBuf[14] = ' ';
BulkBuf[15] = ' ';
BulkBuf[16] = 'L'; /* Product Identification */
BulkBuf[17] = 'P';
BulkBuf[18] = 'C';
BulkBuf[19] = '1';
BulkBuf[20] = '3';
BulkBuf[21] = '4';
BulkBuf[22] = 'x';
BulkBuf[23] = ' ';
BulkBuf[24] = 'D';
BulkBuf[25] = 'i';
BulkBuf[26] = 's';
BulkBuf[27] = 'k';
BulkBuf[28] = ' ';
BulkBuf[29] = ' ';
BulkBuf[30] = ' ';
BulkBuf[31] = ' ';
BulkBuf[32] = '1'; /* Product Revision Level */
BulkBuf[33] = '.';
BulkBuf[34] = '0';
BulkBuf[35] = ' ';
BulkLen = 36;
DataInTransfer();
}
/*
* MSC SCSI Mode Sense (6-Byte) Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_ModeSense6 (void) {
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x03;
BulkBuf[ 1] = 0x00;
BulkBuf[ 2] = 0x00;
BulkBuf[ 3] = 0x00;
BulkLen = 4;
DataInTransfer();
}
/*
* MSC SCSI Mode Sense (10-Byte) Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_ModeSense10 (void) {
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x00;
BulkBuf[ 1] = 0x06;
BulkBuf[ 2] = 0x00;
BulkBuf[ 3] = 0x00;
BulkBuf[ 4] = 0x00;
BulkBuf[ 5] = 0x00;
BulkBuf[ 6] = 0x00;
BulkBuf[ 7] = 0x00;
BulkLen = 8;
DataInTransfer();
}
/*
* MSC SCSI Read Capacity Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_ReadCapacity (void) {
if (!DataInFormat()) return;
/* Last Logical Block */
BulkBuf[ 0] = ((MSC_BlockCount - 1) >> 24) & 0xFF;
BulkBuf[ 1] = ((MSC_BlockCount - 1) >> 16) & 0xFF;
BulkBuf[ 2] = ((MSC_BlockCount - 1) >> 8) & 0xFF;
BulkBuf[ 3] = ((MSC_BlockCount - 1) >> 0) & 0xFF;
/* Block Length */
BulkBuf[ 4] = (MSC_BlockSize >> 24) & 0xFF;
BulkBuf[ 5] = (MSC_BlockSize >> 16) & 0xFF;
BulkBuf[ 6] = (MSC_BlockSize >> 8) & 0xFF;
BulkBuf[ 7] = (MSC_BlockSize >> 0) & 0xFF;
BulkLen = 8;
DataInTransfer();
}
/*
* MSC SCSI Read Format Capacity Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_ReadFormatCapacity (void) {
if (!DataInFormat()) return;
BulkBuf[ 0] = 0x00;
BulkBuf[ 1] = 0x00;
BulkBuf[ 2] = 0x00;
BulkBuf[ 3] = 0x08; /* Capacity List Length */
/* Block Count */
BulkBuf[ 4] = (MSC_BlockCount >> 24) & 0xFF;
BulkBuf[ 5] = (MSC_BlockCount >> 16) & 0xFF;
BulkBuf[ 6] = (MSC_BlockCount >> 8) & 0xFF;
BulkBuf[ 7] = (MSC_BlockCount >> 0) & 0xFF;
/* Block Length */
BulkBuf[ 8] = 0x02; /* Descriptor Code: Formatted Media */
BulkBuf[ 9] = (MSC_BlockSize >> 16) & 0xFF;
BulkBuf[10] = (MSC_BlockSize >> 8) & 0xFF;
BulkBuf[11] = (MSC_BlockSize >> 0) & 0xFF;
BulkLen = 12;
DataInTransfer();
}
/*
* MSC Get Command Block Wrapper Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_GetCBW (void) {
uint32_t n;
for (n = 0; n < BulkLen; n++) {
*((uint8_t *)&CBW + n) = BulkBuf[n];
}
if ((BulkLen == sizeof(CBW)) && (CBW.dSignature == MSC_CBW_Signature)) {
/* Valid CBW */
CSW.dTag = CBW.dTag;
CSW.dDataResidue = CBW.dDataLength;
if ((CBW.bLUN != 0) ||
(CBW.bCBLength < 1) ||
(CBW.bCBLength > 16) ) {
fail:
CSW.bStatus = CSW_CMD_FAILED;
MSC_SetCSW();
} else {
switch (CBW.CB[0]) {
case SCSI_TEST_UNIT_READY:
MSC_TestUnitReady();
break;
case SCSI_REQUEST_SENSE:
MSC_RequestSense();
break;
case SCSI_FORMAT_UNIT:
goto fail;
case SCSI_INQUIRY:
MSC_Inquiry();
break;
case SCSI_START_STOP_UNIT:
goto fail;
case SCSI_MEDIA_REMOVAL:
goto fail;
case SCSI_MODE_SELECT6:
goto fail;
case SCSI_MODE_SENSE6:
MSC_ModeSense6();
break;
case SCSI_MODE_SELECT10:
goto fail;
case SCSI_MODE_SENSE10:
MSC_ModeSense10();
break;
case SCSI_READ_FORMAT_CAPACITIES:
MSC_ReadFormatCapacity();
break;
case SCSI_READ_CAPACITY:
MSC_ReadCapacity();
break;
case SCSI_READ10:
case SCSI_READ12:
if (MSC_RWSetup()) {
if ((CBW.bmFlags & 0x80) != 0) {
BulkStage = MSC_BS_DATA_IN;
MSC_MemoryRead();
} else { /* direction mismatch */
MSC_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
}
}
break;
case SCSI_WRITE10:
case SCSI_WRITE12:
if (MSC_RWSetup()) {
if ((CBW.bmFlags & 0x80) == 0) {
BulkStage = MSC_BS_DATA_OUT;
} else { /* direction mismatch */
MSC_SetStallEP(MSC_EP_IN);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
}
}
break;
case SCSI_VERIFY10:
if ((CBW.CB[1] & 0x02) == 0) {
// BYTCHK = 0 -> CRC Check (not implemented)
CSW.bStatus = CSW_CMD_PASSED;
MSC_SetCSW();
break;
}
if (MSC_RWSetup()) {
if ((CBW.bmFlags & 0x80) == 0) {
BulkStage = MSC_BS_DATA_OUT;
MemOK = TRUE;
} else {
MSC_SetStallEP(MSC_EP_IN);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
}
}
break;
default:
goto fail;
}
}
} else {
/* Invalid CBW */
MSC_SetStallEP(MSC_EP_IN);
/* set EP to stay stalled */
USB_EndPointStall |= (MSC_EP_IN & 0x80) ? ((1 << 16) << (MSC_EP_IN & 0x0F)) : (1 << MSC_EP_IN);
MSC_SetStallEP(MSC_EP_OUT);
/* set EP to stay stalled */
USB_EndPointStall |= (MSC_EP_OUT & 0x80) ? ((1 << 16) << (MSC_EP_OUT & 0x0F)) : (1 << MSC_EP_OUT);
BulkStage = MSC_BS_ERROR;
}
}
/*
* MSC Set Command Status Wrapper Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_SetCSW (void) {
CSW.dSignature = MSC_CSW_Signature;
USB_WriteEP(MSC_EP_IN, (uint8_t *)&CSW, sizeof(CSW));
BulkStage = MSC_BS_CSW;
}
/*
* MSC Bulk In Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_BulkIn (void) {
switch (BulkStage) {
case MSC_BS_DATA_IN:
switch (CBW.CB[0]) {
case SCSI_READ10:
case SCSI_READ12:
MSC_MemoryRead();
break;
}
break;
case MSC_BS_DATA_IN_LAST:
MSC_SetCSW();
break;
case MSC_BS_DATA_IN_LAST_STALL:
MSC_SetStallEP(MSC_EP_IN);
MSC_SetCSW();
break;
case MSC_BS_CSW:
BulkStage = MSC_BS_CBW;
break;
}
}
/*
* MSC Bulk Out Callback
* Parameters: None (global variables)
* Return Value: None
*/
void MSC_BulkOut (void) {
BulkLen = USB_ReadEP(MSC_EP_OUT, BulkBuf);
switch (BulkStage) {
case MSC_BS_CBW:
MSC_GetCBW();
break;
case MSC_BS_DATA_OUT:
switch (CBW.CB[0]) {
case SCSI_WRITE10:
case SCSI_WRITE12:
MSC_MemoryWrite();
break;
case SCSI_VERIFY10:
MSC_MemoryVerify();
break;
}
break;
default:
MSC_SetStallEP(MSC_EP_OUT);
CSW.bStatus = CSW_PHASE_ERROR;
MSC_SetCSW();
break;
}
}

243
firmware/src/serial.c Normal file
View file

@ -0,0 +1,243 @@
/*----------------------------------------------------------------------------
* Name: serial.c
* Purpose: serial port handling for LPC134x
* Version: V1.10
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include "LPC13xx.h" // LPC13xx definitions
#include "type.h"
#include "serial.h"
/*----------------------------------------------------------------------------
Defines for ring buffers
*---------------------------------------------------------------------------*/
#define SER_BUF_SIZE (128) // serial buffer in bytes (power 2)
#define SER_BUF_MASK (SER_BUF_SIZE-1ul) // buffer size mask
/* Buffer read / write macros */
#define SER_BUF_RESET(serBuf) (serBuf.rdIdx = serBuf.wrIdx = 0)
#define SER_BUF_WR(serBuf, dataIn) (serBuf.data[SER_BUF_MASK & serBuf.wrIdx++] = (dataIn))
#define SER_BUF_RD(serBuf) (serBuf.data[SER_BUF_MASK & serBuf.rdIdx++])
#define SER_BUF_EMPTY(serBuf) (serBuf.rdIdx == serBuf.wrIdx)
#define SER_BUF_FULL(serBuf) (serBuf.rdIdx == serBuf.wrIdx+1)
#define SER_BUF_COUNT(serBuf) (SER_BUF_MASK & (serBuf.wrIdx - serBuf.rdIdx))
// buffer type
typedef struct __SER_BUF_T {
unsigned char data[SER_BUF_SIZE];
unsigned int wrIdx;
unsigned int rdIdx;
} SER_BUF_T;
unsigned long ser_txRestart; // NZ if TX restart is required
unsigned short ser_lineState; // ((msr << 8) | (lsr))
SER_BUF_T ser_out; // Serial data buffers
SER_BUF_T ser_in;
/*----------------------------------------------------------------------------
open the serial port
*---------------------------------------------------------------------------*/
void ser_OpenPort (void) {
NVIC_DisableIRQ(UART_IRQn);
LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_6 |= 0x01; /* UART RXD */
LPC_IOCON->PIO1_7 &= ~0x07;
LPC_IOCON->PIO1_7 |= 0x01; /* UART TXD */
/* Enable UART clock */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<12);
LPC_SYSCON->UARTCLKDIV = 0x1; /* divided by 1 */
return;
}
/*----------------------------------------------------------------------------
close the serial port
*---------------------------------------------------------------------------*/
void ser_ClosePort (void) {
LPC_IOCON->PIO1_6 &= ~0x07; /* UART I/O config */
LPC_IOCON->PIO1_7 &= ~0x07;
/* Disable the interrupt in the VIC and UART controllers */
LPC_UART->IER = 0;
NVIC_DisableIRQ(UART_IRQn);
return;
}
/*----------------------------------------------------------------------------
initialize the serial port
*---------------------------------------------------------------------------*/
void ser_InitPort (unsigned long baudrate, unsigned int databits,
unsigned int parity, unsigned int stopbits) {
uint8_t lcr_p, lcr_s, lcr_d;
uint32_t dll;
uint32_t Fdiv;
switch (databits) {
case 5: // 5 Data bits
lcr_d = 0x00;
break;
case 6: // 6 Data bits
lcr_d = 0x01;
break;
case 7: // 7 Data bits
lcr_d = 0x02;
break;
case 8: // 8 Data bits
default:
lcr_d = 0x03;
break;
}
switch (stopbits) {
case 1: // 1,5 Stop bits
case 2: // 2 Stop bits
lcr_s = 0x04;
break;
case 0: // 1 Stop bit
default:
lcr_s = 0x00;
break;
}
switch (parity) {
case 1: // Parity Odd
lcr_p = 0x08;
break;
case 2: // Parity Even
lcr_p = 0x18;
break;
case 3: // Parity Mark
lcr_p = 0x28;
break;
case 4: // Parity Space
lcr_p = 0x38;
break;
case 0: // Parity None
default:
lcr_p = 0x00;
break;
}
SER_BUF_RESET(ser_out); // reset out buffer
SER_BUF_RESET(ser_in); // reset in buffer
/* Note that the pclk is 24,0 MHz. (48.0 MHz / 2) */
/* 24 MHz PCLK generates also rates for 115200, 57600 baud */
Fdiv = LPC_SYSCON->UARTCLKDIV;
dll = (((SystemCoreClock/LPC_SYSCON->SYSAHBCLKDIV)/Fdiv)/16)/baudrate ; /*baud rate */
LPC_UART->FDR = 0; // Fractional divider not used
LPC_UART->LCR = 0x80 | lcr_d | lcr_p | lcr_s; // Data bits, Parity, Stop bit
LPC_UART->DLL = dll; // Baud Rate depending on PCLK
LPC_UART->DLM = (dll >> 8); // High divisor latch
LPC_UART->LCR = 0x00 | lcr_d | lcr_p | lcr_s; // DLAB = 0
LPC_UART->IER = 0x03; // Enable TX/RX interrupts
LPC_UART->FCR = 0x07; /* Enable and reset TX and RX FIFO. */
ser_txRestart = 1; // TX fifo is empty
/* Enable the UART Interrupt */
NVIC_EnableIRQ(UART_IRQn);
return;
}
/*----------------------------------------------------------------------------
read data from serial port
*---------------------------------------------------------------------------*/
int ser_Read (char *buffer, const int *length) {
int bytesToRead, bytesRead;
/* Read *length bytes, block if *bytes are not avaialable */
bytesToRead = *length;
bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);
bytesRead = bytesToRead;
while (bytesToRead--) {
while (SER_BUF_EMPTY(ser_in)); // Block until data is available if none
*buffer++ = SER_BUF_RD(ser_in);
}
return (bytesRead);
}
/*----------------------------------------------------------------------------
write data to the serial port
*---------------------------------------------------------------------------*/
int ser_Write (const char *buffer, int *length) {
int bytesToWrite, bytesWritten;
// Write *length bytes
bytesToWrite = *length;
bytesWritten = bytesToWrite;
while (!SER_BUF_EMPTY(ser_out)); // Block until space is available if none
while (bytesToWrite) {
SER_BUF_WR(ser_out, *buffer++); // Read Rx FIFO to buffer
bytesToWrite--;
}
if (ser_txRestart) {
ser_txRestart = 0;
LPC_UART->THR = SER_BUF_RD(ser_out); // Write to the Tx Register
}
return (bytesWritten);
}
/*----------------------------------------------------------------------------
check if character(s) are available at the serial interface
*---------------------------------------------------------------------------*/
void ser_AvailChar (int *availChar) {
*availChar = SER_BUF_COUNT(ser_in);
}
/*----------------------------------------------------------------------------
read the line state of the serial port
*---------------------------------------------------------------------------*/
void ser_LineState (unsigned short *lineState) {
*lineState = ser_lineState;
ser_lineState = 0;
}
/*----------------------------------------------------------------------------
serial port 1 interrupt
*---------------------------------------------------------------------------*/
void UART_IRQHandler(void)
{
volatile unsigned long iir;
iir = LPC_UART->IIR;
if ((iir & 0x4) || (iir & 0xC)) { // RDA or CTI pending
while (LPC_UART->LSR & 0x01) { // Rx FIFO is not empty
SER_BUF_WR(ser_in, LPC_UART->RBR); // Read Rx FIFO to buffer
}
}
if ((iir & 0x2)) { // TXMIS pending
if (SER_BUF_COUNT(ser_out) != 0) {
LPC_UART->THR = SER_BUF_RD(ser_out); // Write to the Tx FIFO
ser_txRestart = 0;
}
else {
ser_txRestart = 1;
}
}
ser_lineState = LPC_UART->LSR & 0x1E; // update linestate
return;
}

View file

@ -0,0 +1,487 @@
/**************************************************************************//**
* @file system_LPC13xx.c
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Source File
* for the NXP LPC13xx Device Series
* @version V1.02
* @date 18. February 2010
*
* @note
* Copyright (C) 2009 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
// ******** Code Red **************
// * Changed USBCLK_SETUP to 1
// * Changed SYSPLLCTRL_Val to 0x25
// ********************************
#include <stdint.h>
#include "LPC13xx.h"
/*
//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
*/
/*--------------------- Clock Configuration ----------------------------------
//
// <e> Clock Configuration
// <e1> System Clock Setup
// <e2> System Oscillator Enable
// <o3.1> Select System Oscillator Frequency Range
// <0=> 1 - 20 MHz
// <1=> 15 - 25 MHz
// </e2>
// <e4> Watchdog Oscillator Enable
// <o5.0..4> Select Divider for Fclkana
// <0=> 2 <1=> 4 <2=> 6 <3=> 8
// <4=> 10 <5=> 12 <6=> 14 <7=> 16
// <8=> 18 <9=> 20 <10=> 22 <11=> 24
// <12=> 26 <13=> 28 <14=> 30 <15=> 32
// <16=> 34 <17=> 36 <18=> 38 <19=> 40
// <20=> 42 <21=> 44 <22=> 46 <23=> 48
// <24=> 50 <25=> 52 <26=> 54 <27=> 56
// <28=> 58 <29=> 60 <30=> 62 <31=> 64
// <o5.5..8> Select Watchdog Oscillator Analog Frequency (Fclkana)
// <0=> Disabled
// <1=> 0.5 MHz
// <2=> 0.8 MHz
// <3=> 1.1 MHz
// <4=> 1.4 MHz
// <5=> 1.6 MHz
// <6=> 1.8 MHz
// <7=> 2.0 MHz
// <8=> 2.2 MHz
// <9=> 2.4 MHz
// <10=> 2.6 MHz
// <11=> 2.7 MHz
// <12=> 2.9 MHz
// <13=> 3.1 MHz
// <14=> 3.2 MHz
// <15=> 3.4 MHz
// </e4>
// <o6> Select Input Clock for sys_pllclkin (Register: SYSPLLCLKSEL)
// <0=> IRC Oscillator
// <1=> System Oscillator
// <2=> WDT Oscillator
// <3=> Invalid
// <e7> Use System PLL
// <i> F_pll = M * F_in
// <i> F_in must be in the range of 10 MHz to 25 MHz
// <o8.0..4> M: PLL Multiplier Selection
// <1-32><#-1>
// <o8.5..6> P: PLL Divider Selection
// <0=> 2
// <1=> 4
// <2=> 8
// <3=> 16
// <o8.7> DIRECT: Direct CCO Clock Output Enable
// <o8.8> BYPASS: PLL Bypass Enable
// </e7>
// <o9> Select Input Clock for Main clock (Register: MAINCLKSEL)
// <0=> IRC Oscillator
// <1=> Input Clock to System PLL
// <2=> WDT Oscillator
// <3=> System PLL Clock Out
// </e1>
// <e10> USB Clock Setup
// <e11> Use USB PLL
// <i> F_pll = M * F_in
// <i> F_in must be in the range of 10 MHz to 25 MHz
// <o12.0..1> Select Input Clock for usb_pllclkin (Register: USBPLLCLKSEL)
// <0=> IRC Oscillator
// <1=> System Oscillator
// <o13.0..4> M: PLL Multiplier Selection
// <1-32><#-1>
// <o13.5..6> P: PLL Divider Selection
// <0=> 2
// <1=> 4
// <2=> 8
// <3=> 16
// <o13.7> DIRECT: Direct CCO Clock Output Enable
// <o13.8> BYPASS: PLL Bypass Enable
// </e11>
// </e10>
// <o14.0..7> System AHB Divider <0-255>
// <i> 0 = is disabled
// <o15.0> SYS Clock Enable
// <o15.1> ROM Clock Enable
// <o15.2> RAM Clock Enable
// <o15.3> FLASH1 Clock Enable
// <o15.4> FLASH2 Clock Enable
// <o15.5> I2C Clock Enable
// <o15.6> GPIO Clock Enable
// <o15.7> CT16B0 Clock Enable
// <o15.8> CT16B1 Clock Enable
// <o15.9> CT32B0 Clock Enable
// <o15.10> CT32B1 Clock Enable
// <o15.11> SSP Clock Enable
// <o15.12> UART Clock Enable
// <o15.13> ADC Clock Enable
// <o15.14> USB_REG Clock Enable
// <o15.15> SWDT Clock Enable
// <o15.16> IOCON Clock Enable
// </e>
*/
#define CLOCK_SETUP 1
#define SYSCLK_SETUP 1
#define SYSOSC_SETUP 1
#define SYSOSCCTRL_Val 0x00000000
#define WDTOSC_SETUP 0
#define WDTOSCCTRL_Val 0x000000A0
#define SYSPLLCLKSEL_Val 0x00000001
#define SYSPLL_SETUP 1
#define SYSPLLCTRL_Val 0x00000025
#define MAINCLKSEL_Val 0x00000003
// ******** Code Red *********
// * Changed USBCLK_SETUP to 1
// ***************************
#define USBCLK_SETUP 1
#define USBPLL_SETUP 1
#define USBPLLCLKSEL_Val 0x00000001
#define USBPLLCTRL_Val 0x00000003
#define SYSAHBCLKDIV_Val 0x00000001
#define AHBCLKCTRL_Val 0x0001005F
/*--------------------- Memory Mapping Configuration -------------------------
//
// <e> Memory Mapping
// <o1.0..1> System Memory Remap (Register: SYSMEMREMAP)
// <0=> Bootloader mapped to address 0
// <1=> RAM mapped to address 0
// <2=> Flash mapped to address 0
// <3=> Flash mapped to address 0
// </e>
*/
#define MEMMAP_SETUP 0
#define SYSMEMREMAP_Val 0x00000001
/*
//-------- <<< end of configuration section >>> ------------------------------
*/
/*----------------------------------------------------------------------------
Check the register settings
*----------------------------------------------------------------------------*/
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
/* Clock Configuration -------------------------------------------------------*/
#if (CHECK_RSVD((SYSOSCCTRL_Val), ~0x00000003))
#error "SYSOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((WDTOSCCTRL_Val), ~0x000001FF))
#error "WDTOSCCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSPLLCLKSEL_Val), 0, 2))
#error "SYSPLLCLKSEL: Value out of range!"
#endif
#if (CHECK_RSVD((SYSPLLCTRL_Val), ~0x000001FF))
#error "SYSPLLCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((MAINCLKSEL_Val), ~0x00000003))
#error "MAINCLKSEL: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((USBPLLCLKSEL_Val), 0, 1))
#error "USBPLLCLKSEL: Value out of range!"
#endif
#if (CHECK_RSVD((USBPLLCTRL_Val), ~0x000001FF))
#error "USBPLLCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((USBPLLUEN_Val), ~0x00000001))
#error "USBPLLUEN: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((SYSAHBCLKDIV_Val), 0, 255))
#error "SYSAHBCLKDIV: Value out of range!"
#endif
#if (CHECK_RSVD((AHBCLKCTRL_Val), ~0x0001FFFF))
#error "AHBCLKCTRL: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((SYSMEMREMAP_Val), ~0x00000003))
#error "SYSMEMREMAP: Invalid values of reserved bits!"
#endif
/*----------------------------------------------------------------------------
DEFINES
*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define __XTAL (12000000UL) /* Oscillator frequency */
#define __SYS_OSC_CLK ( __XTAL) /* Main oscillator frequency */
#define __IRC_OSC_CLK (12000000UL) /* Internal RC oscillator frequency */
#define __FREQSEL ((WDTOSCCTRL_Val >> 5) & 0x0F)
#define __DIVSEL (((WDTOSCCTRL_Val & 0x1F) << 1) + 2)
#if (CLOCK_SETUP) /* Clock Setup */
#if (SYSCLK_SETUP) /* System Clock Setup */
#if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
#if (__FREQSEL == 0)
#define __WDT_OSC_CLK ( 400000 / __DIVSEL)
#elif (__FREQSEL == 1)
#define __WDT_OSC_CLK ( 500000 / __DIVSEL)
#elif (__FREQSEL == 2)
#define __WDT_OSC_CLK ( 800000 / __DIVSEL)
#elif (__FREQSEL == 3)
#define __WDT_OSC_CLK (1100000 / __DIVSEL)
#elif (__FREQSEL == 4)
#define __WDT_OSC_CLK (1400000 / __DIVSEL)
#elif (__FREQSEL == 5)
#define __WDT_OSC_CLK (1600000 / __DIVSEL)
#elif (__FREQSEL == 6)
#define __WDT_OSC_CLK (1800000 / __DIVSEL)
#elif (__FREQSEL == 7)
#define __WDT_OSC_CLK (2000000 / __DIVSEL)
#elif (__FREQSEL == 8)
#define __WDT_OSC_CLK (2200000 / __DIVSEL)
#elif (__FREQSEL == 9)
#define __WDT_OSC_CLK (2400000 / __DIVSEL)
#elif (__FREQSEL == 10)
#define __WDT_OSC_CLK (2600000 / __DIVSEL)
#elif (__FREQSEL == 11)
#define __WDT_OSC_CLK (2700000 / __DIVSEL)
#elif (__FREQSEL == 12)
#define __WDT_OSC_CLK (2900000 / __DIVSEL)
#elif (__FREQSEL == 13)
#define __WDT_OSC_CLK (3100000 / __DIVSEL)
#elif (__FREQSEL == 14)
#define __WDT_OSC_CLK (3200000 / __DIVSEL)
#else
#define __WDT_OSC_CLK (3400000 / __DIVSEL)
#endif
#else
#define __WDT_OSC_CLK (1600000 / 2)
#endif // WDTOSC_SETUP
/* sys_pllclkin calculation */
#if ((SYSPLLCLKSEL_Val & 0x03) == 0)
#define __SYS_PLLCLKIN (__IRC_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 1)
#define __SYS_PLLCLKIN (__SYS_OSC_CLK)
#elif ((SYSPLLCLKSEL_Val & 0x03) == 2)
#define __SYS_PLLCLKIN (__WDT_OSC_CLK)
#else
#define __SYS_PLLCLKIN (0)
#endif
#if (SYSPLL_SETUP) /* System PLL Setup */
#define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * ((SYSPLLCTRL_Val & 0x01F) + 1))
#else
#define __SYS_PLLCLKOUT (__SYS_PLLCLKIN * (1))
#endif // SYSPLL_SETUP
/* main clock calculation */
#if ((MAINCLKSEL_Val & 0x03) == 0)
#define __MAIN_CLOCK (__IRC_OSC_CLK)
#elif ((MAINCLKSEL_Val & 0x03) == 1)
#define __MAIN_CLOCK (__SYS_PLLCLKIN)
#elif ((MAINCLKSEL_Val & 0x03) == 2)
#define __MAIN_CLOCK (__WDT_OSC_CLK)
#elif ((MAINCLKSEL_Val & 0x03) == 3)
#define __MAIN_CLOCK (__SYS_PLLCLKOUT)
#else
#define __MAIN_CLOCK (0)
#endif
#define __SYSTEM_CLOCK (__MAIN_CLOCK / SYSAHBCLKDIV_Val)
#else // SYSCLK_SETUP
#if (SYSAHBCLKDIV_Val == 0)
#define __SYSTEM_CLOCK (0)
#else
#define __SYSTEM_CLOCK (__XTAL / SYSAHBCLKDIV_Val)
#endif
#endif // SYSCLK_SETUP
#else
#define __SYSTEM_CLOCK (__XTAL)
#endif // CLOCK_SETUP
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
uint32_t wdt_osc = 0;
/* Determine clock frequency according to clock register values */
switch ((LPC_SYSCON->WDTOSCCTRL >> 5) & 0x0F) {
case 0: wdt_osc = 400000; break;
case 1: wdt_osc = 500000; break;
case 2: wdt_osc = 800000; break;
case 3: wdt_osc = 1100000; break;
case 4: wdt_osc = 1400000; break;
case 5: wdt_osc = 1600000; break;
case 6: wdt_osc = 1800000; break;
case 7: wdt_osc = 2000000; break;
case 8: wdt_osc = 2200000; break;
case 9: wdt_osc = 2400000; break;
case 10: wdt_osc = 2600000; break;
case 11: wdt_osc = 2700000; break;
case 12: wdt_osc = 2900000; break;
case 13: wdt_osc = 3100000; break;
case 14: wdt_osc = 3200000; break;
case 15: wdt_osc = 3400000; break;
}
wdt_osc /= ((LPC_SYSCON->WDTOSCCTRL & 0x1F) << 1) + 2;
switch (LPC_SYSCON->MAINCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* Input Clock to System PLL */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
SystemCoreClock = __IRC_OSC_CLK;
break;
case 1: /* System oscillator */
SystemCoreClock = __SYS_OSC_CLK;
break;
case 2: /* WDT Oscillator */
SystemCoreClock = wdt_osc;
break;
case 3: /* Reserved */
SystemCoreClock = 0;
break;
}
break;
case 2: /* WDT Oscillator */
SystemCoreClock = wdt_osc;
break;
case 3: /* System PLL Clock Out */
switch (LPC_SYSCON->SYSPLLCLKSEL & 0x03) {
case 0: /* Internal RC oscillator */
if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
SystemCoreClock = __IRC_OSC_CLK;
} else {
SystemCoreClock = __IRC_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
}
break;
case 1: /* System oscillator */
if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
SystemCoreClock = __SYS_OSC_CLK;
} else {
SystemCoreClock = __SYS_OSC_CLK * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
}
break;
case 2: /* WDT Oscillator */
if (LPC_SYSCON->SYSPLLCTRL & 0x180) {
SystemCoreClock = wdt_osc;
} else {
SystemCoreClock = wdt_osc * ((LPC_SYSCON->SYSPLLCTRL & 0x01F) + 1);
}
break;
case 3: /* Reserved */
SystemCoreClock = 0;
break;
}
break;
}
SystemCoreClock /= LPC_SYSCON->SYSAHBCLKDIV;
}
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void)
{
#if (CLOCK_SETUP) /* Clock Setup */
#if (SYSCLK_SETUP) /* System Clock Setup */
#if (SYSOSC_SETUP) /* System Oscillator Setup */
uint32_t i;
LPC_SYSCON->PDRUNCFG &= ~(1 << 5); /* Power-up System Osc */
LPC_SYSCON->SYSOSCCTRL = SYSOSCCTRL_Val;
for (i = 0; i < 200; i++) __NOP();
LPC_SYSCON->SYSPLLCLKSEL = SYSPLLCLKSEL_Val; /* Select PLL Input */
LPC_SYSCON->SYSPLLCLKUEN = 0x01; /* Update Clock Source */
LPC_SYSCON->SYSPLLCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->SYSPLLCLKUEN = 0x01;
while (!(LPC_SYSCON->SYSPLLCLKUEN & 0x01)); /* Wait Until Updated */
#if (SYSPLL_SETUP) /* System PLL Setup */
LPC_SYSCON->SYSPLLCTRL = SYSPLLCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 7); /* Power-up SYSPLL */
while (!(LPC_SYSCON->SYSPLLSTAT & 0x01)); /* Wait Until PLL Locked */
#endif
#endif
#if (WDTOSC_SETUP) /* Watchdog Oscillator Setup*/
LPC_SYSCON->WDTOSCCTRL = WDTOSCCTRL_Val;
LPC_SYSCON->PDRUNCFG &= ~(1 << 6); /* Power-up WDT Clock */
#endif
LPC_SYSCON->MAINCLKSEL = MAINCLKSEL_Val; /* Select PLL Clock Output */
LPC_SYSCON->MAINCLKUEN = 0x01; /* Update MCLK Clock Source */
LPC_SYSCON->MAINCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->MAINCLKUEN = 0x01;
while (!(LPC_SYSCON->MAINCLKUEN & 0x01)); /* Wait Until Updated */
#endif
#if (USBCLK_SETUP) /* USB Clock Setup */
LPC_SYSCON->PDRUNCFG &= ~(1 << 10); /* Power-up USB PHY */
#if (USBPLL_SETUP) /* USB PLL Setup */
LPC_SYSCON->PDRUNCFG &= ~(1 << 8); /* Power-up USB PLL */
LPC_SYSCON->USBPLLCLKSEL = USBPLLCLKSEL_Val; /* Select PLL Input */
LPC_SYSCON->USBPLLCLKUEN = 0x01; /* Update Clock Source */
LPC_SYSCON->USBPLLCLKUEN = 0x00; /* Toggle Update Register */
LPC_SYSCON->USBPLLCLKUEN = 0x01;
while (!(LPC_SYSCON->USBPLLCLKUEN & 0x01)); /* Wait Until Updated */
LPC_SYSCON->USBPLLCTRL = USBPLLCTRL_Val;
while (!(LPC_SYSCON->USBPLLSTAT & 0x01)); /* Wait Until PLL Locked */
LPC_SYSCON->USBCLKSEL = 0x00; /* Select USB PLL */
#else
LPC_SYSCON->USBCLKSEL = 0x01; /* Select Main Clock */
#endif
#else
LPC_SYSCON->PDRUNCFG |= (1 << 10); /* Power-down USB PHY */
LPC_SYSCON->PDRUNCFG |= (1 << 8); /* Power-down USB PLL */
#endif
LPC_SYSCON->SYSAHBCLKDIV = SYSAHBCLKDIV_Val;
LPC_SYSCON->SYSAHBCLKCTRL = AHBCLKCTRL_Val;
#endif
#if (MEMMAP_SETUP || MEMMAP_INIT) /* Memory Mapping Setup */
LPC_SYSCON->SYSMEMREMAP = SYSMEMREMAP_Val;
#endif
}

153
firmware/src/usbcomp.c Normal file
View file

@ -0,0 +1,153 @@
/*----------------------------------------------------------------------------
* Name: vcomdemo.c
* Purpose: USB virtual COM port Demo
* Version: V1.02
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include "LPC13xx.h"
#include "type.h"
#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "cdc.h"
#include "cdcuser.h"
#include "serial.h"
#include "vcomdemo.h"
#include "mscuser.h"
#include "memory.h"
#include "stdio.h"
#include "string.h"
#include "edubrm.h"
extern uint8_t Memory[MSC_MemorySize]; /* MSC Memory in RAM */
#define EN_TIMER32_1 (1<<10)
#define EN_IOCON (1<<16)
#define EN_USBREG (1<<14)
/*----------------------------------------------------------------------------
Initializes the VCOM port.
Call this function before using VCOM_putchar or VCOM_getchar
*---------------------------------------------------------------------------*/
void VCOM_Init(void) {
CDC_Init ();
}
/*----------------------------------------------------------------------------
Reads character from serial port buffer and writes to USB buffer
*---------------------------------------------------------------------------*/
void VCOM_Serial2Usb(void) {
static char serBuf [USB_CDC_BUFSIZE];
int numBytesRead, numAvailByte;
ser_AvailChar (&numAvailByte);
if (numAvailByte > 0) {
if (CDC_DepInEmpty) {
numBytesRead = ser_Read (&serBuf[0], &numAvailByte);
CDC_DepInEmpty = 0;
USB_WriteEP (CDC_DEP_IN, (unsigned char *)&serBuf[0], numBytesRead);
}
}
}
/*----------------------------------------------------------------------------
Reads character from USB buffer and writes to serial port buffer
*---------------------------------------------------------------------------*/
void VCOM_Usb2Serial(void) {
static char serBuf [32];
int numBytesToRead, numBytesRead, numAvailByte;
CDC_OutBufAvailChar (&numAvailByte);
if (numAvailByte > 0) {
numBytesToRead = numAvailByte > 32 ? 32 : numAvailByte;
numBytesRead = CDC_RdOutBuf (&serBuf[0], &numBytesToRead);
ser_Write (&serBuf[0], &numBytesRead);
}
}
/*----------------------------------------------------------------------------
Reads character from USB buffer and writes to serial port buffer
*---------------------------------------------------------------------------*/
void VCOM_Usb2SerialTest(void) {
static char serBuf [32];
int numBytesRead;
strcpy(serBuf,"Test\n");
numBytesRead = strlen(serBuf);
ser_Write (&serBuf[0], &numBytesRead);
}
/*----------------------------------------------------------------------------
checks the serial state and initiates notification
*---------------------------------------------------------------------------*/
void VCOM_CheckSerialState (void) {
unsigned short temp;
static unsigned short serialState;
temp = CDC_GetSerialState();
if (serialState != temp) {
serialState = temp;
CDC_NotificationIn(); // send SERIAL_STATE notification
}
}
/*----------------------------------------------------------------------------
Main Program
*---------------------------------------------------------------------------*/
int main (void) {
uint32_t n;
for (n = 0; n < MSC_ImageSize; n++) { /* Copy Initial Disk Image */
Memory[n] = DiskImage[n]; /* from Flash to RAM */
}
/* Basic chip initialization is taken care of in SystemInit() called
* from the startup code. SystemInit() and chip settings are defined
* in the CMSIS system_<part family>.c file.
*/
/* Enable Timer32_1, IOCON, and USB blocks */
LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);
USBIOClkConfig();
VCOM_Init(); // VCOM Initialization
USB_Init(); // USB Initialization
USB_Connect(TRUE); // USB Connect
while (!USB_Configuration) ; // wait until USB is configured
//VCOM_Usb2SerialTest();
enableLED();
while (1) { // Loop forever
VCOM_Brm2Usb();
VCOM_CheckSerialState();
VCOM_Usb2Brm();
} // end while
} // end main ()

1085
firmware/src/usbcore.c Normal file

File diff suppressed because it is too large Load diff

279
firmware/src/usbdesc.c Normal file
View file

@ -0,0 +1,279 @@
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: usbdesc.c
* Purpose: USB Descriptors
* Version: V1.20
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------
* History:
* V1.20 Changed string descriptor handling
* V1.00 Initial Version
*---------------------------------------------------------------------------*/
#include "type.h"
#include "usb.h"
#include "cdc.h"
#include "usbcfg.h"
#include "usbdesc.h"
#include "msc.h"
#include "config.h"
/* USB Standard Device Descriptor */
const uint8_t USB_DeviceDescriptor[] = {
USB_DEVICE_DESC_SIZE, /* bLength */
USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL(0x0200), /* 2.0 */ /* bcdUSB */
USB_DEVICE_CLASS_MISCELLANEOUS, /* bDeviceClass */
0x02, /* bDeviceSubClass */
0x01, /* bDeviceProtocol */
USB_MAX_PACKET0, /* bMaxPacketSize0 */
// 0x70, 0x08, /* idVendorL */ //this vendor code is here in order to bypase linux probing for ttyACM0
// 0x01, 0x00, /* idProductL */ //this product code is here in order to bypase linux probing for ttyACM0
WBVAL(USB_VENDOR_ID), /* idVendor */
WBVAL(USB_PROD_ID), /* idProduct */
WBVAL(USB_DEVICE), /* 1.00 */ /* bcdDevice */
0x01, /* iManufacturer */
0x02, /* iProduct */
0x03, /* iSerialNumber */
0x01 /* bNumConfigurations: one possible configuration*/
};
/* USB Configuration Descriptor */
/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor) */
const uint8_t USB_ConfigDescriptor[] = {
/* Configuration 1 */
USB_CONFIGUARTION_DESC_SIZE, /* bLength */
USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL( /* wTotalLength */
1*USB_CONFIGUARTION_DESC_SIZE +
1*USB_INTERFACE_DESC_SIZE + /* mass storage interface */
2*USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */
1*USB_INTERFACE_ASSOCIATION_DESC_SIZE + /* interface association */
1*USB_INTERFACE_DESC_SIZE + /* communication interface */
0x0013 + /* CDC functions */
1*USB_ENDPOINT_DESC_SIZE + /* interrupt endpoint */
1*USB_INTERFACE_DESC_SIZE + /* data interface */
2*USB_ENDPOINT_DESC_SIZE + /* bulk endpoints */
0
),
0x03, /* bNumInterfaces */
0x01, /* bConfigurationValue: 0x01 is used to select this configuration */
0x00, /* iConfiguration: no string to describe this configuration */
USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */
/*USB_CONFIG_REMOTE_WAKEUP*/,
USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */
/* Interface 0, Alternate Setting 0, MSC Class */
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_MSC_IF_NUM, /* bInterfaceNumber */
0x00, /* bAlternateSetting */
0x02, /* bNumEndpoints */
USB_DEVICE_CLASS_STORAGE, /* bInterfaceClass */
MSC_SUBCLASS_SCSI, /* bInterfaceSubClass */
MSC_PROTOCOL_BULK_ONLY, /* bInterfaceProtocol */
0x04, /* iInterface */
/* Endpoint, EP2 Bulk IN */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(2), /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(0x0040), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Endpoint, EP2 Bulk OUT */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_OUT(2), /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(0x0040), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* IAD to associate the two CDC interfaces */
USB_INTERFACE_ASSOCIATION_DESC_SIZE, /* bLength */
USB_INTERFACE_ASSOCIATION_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_CIF_NUM, /* bFirstInterface */
2, /* bInterfaceCount */
CDC_COMMUNICATION_INTERFACE_CLASS, /* bFunctionClass */
CDC_ABSTRACT_CONTROL_MODEL, /* bFunctionSubClass */
0, /* bFunctionProtocol */
0x06, /* iFunction (Index of string descriptor describing this function) */
/* Interface 0, Alternate Setting 0, Communication class interface descriptor */
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_CIF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints: One endpoint used */
CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass: Communication Interface Class */
CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass: Abstract Control Model */
0x00, /* bInterfaceProtocol: no protocol used */
0x05, /* iInterface: */
/*Header Functional Descriptor*/
0x05, /* bLength: Endpoint Descriptor size */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_HEADER, /* bDescriptorSubtype: Header Func Desc */
WBVAL(CDC_V1_10), /* 1.10 */ /* bcdCDC */
/*Call Management Functional Descriptor*/
0x05, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_CALL_MANAGEMENT, /* bDescriptorSubtype: Call Management Func Desc */
0x01, /* bmCapabilities: device handles call management */
USB_CDC_DIF_NUM, /* bDataInterface: CDC data IF ID */
/*Abstract Control Management Functional Descriptor*/
0x04, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_ABSTRACT_CONTROL_MANAGEMENT, /* bDescriptorSubtype: Abstract Control Management desc */
0x02, /* bmCapabilities: SET_LINE_CODING, GET_LINE_CODING, SET_CONTROL_LINE_STATE supported */
/*Union Functional Descriptor*/
0x05, /* bFunctionLength */
CDC_CS_INTERFACE, /* bDescriptorType: CS_INTERFACE */
CDC_UNION, /* bDescriptorSubtype: Union func desc */
USB_CDC_CIF_NUM, /* bMasterInterface: Communication class interface is master */
USB_CDC_DIF_NUM, /* bSlaveInterface0: Data class interface is slave 0 */
/*Endpoint 1 Descriptor*/ /* event notification (optional) */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(1), /* bEndpointAddress */
USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */
WBVAL(0x0010), /* wMaxPacketSize */
0x02, /* 2ms */ /* bInterval */
/* Interface 1, Alternate Setting 0, Data class interface descriptor*/
USB_INTERFACE_DESC_SIZE, /* bLength */
USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_CDC_DIF_NUM, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: no alternate setting */
0x02, /* bNumEndpoints: two endpoints used */
CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass: Data Interface Class */
0x00, /* bInterfaceSubClass: no subclass available */
0x00, /* bInterfaceProtocol: no protocol used */
0x05, /* iInterface: */
/* Endpoint, EP3 Bulk Out */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_OUT(3), /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(USB_CDC_BUFSIZE), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Endpoint, EP3 Bulk In */
USB_ENDPOINT_DESC_SIZE, /* bLength */
USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */
USB_ENDPOINT_IN(3), /* bEndpointAddress */
USB_ENDPOINT_TYPE_BULK, /* bmAttributes */
WBVAL(USB_CDC_BUFSIZE), /* wMaxPacketSize */
0x00, /* bInterval: ignore for Bulk transfer */
/* Terminator */
0 /* bLength */
};
/* USB String Descriptor (optional) */
const uint8_t USB_StringDescriptor[] = {
/* Index 0x00: LANGID Codes */
0x04, /* bLength */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
WBVAL(0x0409), /* US English */ /* wLANGID */
/* Index 0x01: Manufacturer */
(13*2 + 2), /* bLength (13 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'N',0,
'X',0,
'P',0,
' ',0,
'S',0,
'E',0,
'M',0,
'I',0,
'C',0,
'O',0,
'N',0,
'D',0,
' ',0,
/* Index 0x02: Product */
(21*2 + 2), /* bLength ( 21 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'N',0,
'X',0,
'P',0,
' ',0,
'L',0,
'P',0,
'C',0,
'1',0,
'3',0,
'x',0,
'x',0,
' ',0,
'M',0,
'S',0,
'D',0,
'/',0,
'V',0,
'C',0,
'O',0,
'M',0,
' ',0,
/* Index 0x03: Serial Number */
(16*2 + 2), /* bLength (12 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'C',0,
'O',0,
'M',0,
'P',0,
'O',0,
'S',0,
'I',0,
'T',0,
'E',0,
' ',0,
'D',0,
'E',0,
'M',0,
'O',0,
' ',0,
' ',0,
/* Index 0x04: Interface 0, Alternate Setting 0 */
( 6*2 + 2), /* bLength (6 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'M',0,
'e',0,
'm',0,
'o',0,
'r',0,
'y',0,
/* Index 0x05: Interface 0, Alternate Setting 0 */
( 4*2 + 2), /* bLength (4 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'V',0,
'C',0,
'O',0,
'M',0,
/* Index 0x05: Interface 0, Alternate Setting 0 */
( 8*2 + 2), /* bLength (4 Char + Type + lenght) */
USB_STRING_DESCRIPTOR_TYPE, /* bDescriptorType */
'C',0,
'O',0,
'M',0,
'/',0,
'D',0,
'A',0,
'T',0,
'A',0,
};

552
firmware/src/usbhw.c Normal file
View file

@ -0,0 +1,552 @@
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: usbhw.c
* Purpose: USB Hardware Layer Module for Philips LPC17xx
* Version: V1.20
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------
* History:
* V1.20 Added USB_ClearEPBuf
* V1.00 Initial Version
*----------------------------------------------------------------------------*/
#include "LPC13xx.h" /* LPC13xx definitions */
#include "usb.h"
#include "usbcfg.h"
#include "usbreg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "usbuser.h"
/*
* USB and IO Clock configuration only.
* The same as call PeriClkIOInit(IOCON_USB);
* The purpose is to reduce the code space for
* overall USB project and reserve code space for
* USB debugging.
* Parameters: None
* Return Value: None
*/
void USBIOClkConfig( void )
{
/* Enable AHB clock to the GPIO domain. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);
LPC_IOCON->PIO0_1 &= ~0x07;
LPC_IOCON->PIO0_1 |= 0x01; /* CLK OUT */
/* Enable AHB clock to the USB block. */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<14);
LPC_IOCON->PIO0_3 &= ~0x1F;
LPC_IOCON->PIO0_3 |= 0x01; /* Secondary function VBUS */
LPC_IOCON->PIO0_6 &= ~0x07;
LPC_IOCON->PIO0_6 |= 0x01; /* Secondary function SoftConn */
return;
}
/*
* Delay number of clock cycles
* Parameters: Delay length
* Return Value: None
*/
void delay (uint32_t length ) {
uint32_t i;
for ( i = 0; i < length; i++ );
return;
}
/*
* Get Endpoint Physical Address
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: Endpoint Physical Address
*/
uint32_t EPAdr (uint32_t EPNum) {
uint32_t val;
val = (EPNum & 0x0F) << 1;
if (EPNum & 0x80) {
val += 1;
}
return (val);
}
/*
* Write Command
* Parameters: cmd: Command
* Return Value: None
*/
void WrCmd (uint32_t cmd) {
LPC_USB->DevIntClr = CCEMTY_INT;
LPC_USB->CmdCode = cmd;
while ((LPC_USB->DevIntSt & (CCEMTY_INT | DEV_STAT_INT)) == 0);
}
/*
* Write Command Data
* Parameters: cmd: Command
* val: Data
* Return Value: None
*/
void WrCmdDat (uint32_t cmd, uint32_t val) {
WrCmd(cmd);
WrCmd(val);
}
/*
* Write Command to Endpoint
* Parameters: cmd: Command
* val: Data
* Return Value: None
*/
void WrCmdEP (uint32_t EPNum, uint32_t cmd){
WrCmd(CMD_SEL_EP(EPAdr(EPNum)));
WrCmd(cmd);
}
/*
* Read Command Data
* Parameters: cmd: Command
* Return Value: Data Value
*/
uint32_t RdCmdDat (uint32_t cmd) {
LPC_USB->DevIntClr = CCEMTY_INT | CDFULL_INT;
LPC_USB->CmdCode = cmd;
while ((LPC_USB->DevIntSt & (CDFULL_INT | DEV_STAT_INT)) == 0);
return (LPC_USB->CmdData);
}
/*
* USB Initialize Function
* Called by the User to initialize USB
* Return Value: None
*/
void USB_Init (void) {
#if USB_FIQ_EVENT
/* It's important that only BULK and FRAME(ISO) can be routed
to FIQ. */
LPC_USB->DevFIQSel = 0x01; /* SOF Use FIQ */
/* Enable the USB Interrupt */
NVIC_EnableIRQ(USB_FIQn);
#endif
/* Enable the USB Interrupt */
NVIC_EnableIRQ(USB_IRQn);
USB_Reset();
USB_SetAddress(0);
return;
}
/*
* USB Connect Function
* Called by the User to Connect/Disconnect USB
* Parameters: con: Connect/Disconnect
* Return Value: None
*/
void USB_Connect (uint32_t con) {
WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con ? DEV_CON : 0));
}
/*
* USB Reset Function
* Called automatically on USB Reset
* Return Value: None
*/
void USB_Reset (void) {
LPC_USB->DevIntClr = 0x000FFFFF;
/* Enable all eight(8) EPs, note: EP won't be ready until it's
configured/enabled when device sending SetEPStatus command
to the command engine. */
LPC_USB->DevIntEn = DEV_STAT_INT | (0xFF<<1) |
(USB_SOF_EVENT ? FRAME_INT : 0);
return;
}
/*
* USB Suspend Function
* Called automatically on USB Suspend
* Return Value: None
*/
void USB_Suspend (void) {
/* Performed by Hardware */
}
/*
* USB Resume Function
* Called automatically on USB Resume
* Return Value: None
*/
void USB_Resume (void) {
/* Performed by Hardware */
}
/*
* USB Remote Wakeup Function
* Called automatically on USB Remote Wakeup
* Return Value: None
*/
void USB_WakeUp (void) {
if (USB_DeviceStatus & USB_GETSTATUS_REMOTE_WAKEUP) {
WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(DEV_CON));
}
}
/*
* USB Remote Wakeup Configuration Function
* Parameters: cfg: Enable/Disable
* Return Value: None
*/
void USB_WakeUpCfg (uint32_t cfg) {
cfg = cfg; /* Not needed */
}
/*
* USB Set Address Function
* Parameters: adr: USB Address
* Return Value: None
*/
void USB_SetAddress (uint32_t adr) {
WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Don't wait for next */
WrCmdDat(CMD_SET_ADDR, DAT_WR_BYTE(DEV_EN | adr)); /* Setup Status Phase */
}
/*
* USB Configure Function
* Parameters: cfg: Configure/Deconfigure
* Return Value: None
*/
void USB_Configure (uint32_t cfg) {
WrCmdDat(CMD_CFG_DEV, DAT_WR_BYTE(cfg ? CONF_DVICE : 0));
return;
}
/*
* Configure USB Endpoint according to Descriptor
* Parameters: pEPD: Pointer to Endpoint Descriptor
* Return Value: None
*/
void USB_ConfigEP (USB_ENDPOINT_DESCRIPTOR *pEPD) {
return;
}
/*
* Set Direction for USB Control Endpoint
* Parameters: dir: Out (dir == 0), In (dir <> 0)
* Return Value: None
*/
void USB_DirCtrlEP (uint32_t dir) {
dir = dir; /* Not needed */
}
/*
* Enable USB Endpoint
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void USB_EnableEP (uint32_t EPNum) {
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
}
/*
* Disable USB Endpoint
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void USB_DisableEP (uint32_t EPNum) {
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_DA));
}
/*
* Reset USB Endpoint
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void USB_ResetEP (uint32_t EPNum) {
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
}
/*
* Set Stall for USB Endpoint
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void USB_SetStallEP (uint32_t EPNum) {
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(EP_STAT_ST));
}
/*
* Clear Stall for USB Endpoint
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void USB_ClrStallEP (uint32_t EPNum) {
WrCmdDat(CMD_SET_EP_STAT(EPAdr(EPNum)), DAT_WR_BYTE(0));
}
/*
* Clear USB Endpoint Buffer
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: None
*/
void USB_ClearEPBuf (uint32_t EPNum) {
WrCmdEP(EPNum, CMD_CLR_BUF);
}
/*
* Read USB Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* Return Value: Number of bytes read
*/
uint32_t USB_ReadEP (uint32_t EPNum, uint8_t *pData) {
uint32_t cnt, n;
LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_RD_EN;
/* 3 clock cycles to fetch the packet length from RAM. */
delay( 5 );
do {
cnt = LPC_USB->RxPLen;
} while ((cnt & PKT_DV) == 0);
cnt &= PKT_LNGTH_MASK;
for (n = 0; n < (cnt + 3) / 4; n++) {
*((uint32_t __attribute__((packed)) *)pData) = LPC_USB->RxData;
pData += 4;
}
LPC_USB->Ctrl = 0;
if ((EPNum & 0x80) != 0x04) { /* Non-Isochronous Endpoint */
WrCmdEP(EPNum, CMD_CLR_BUF);
}
return (cnt);
}
/*
* Write USB Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* cnt: Number of bytes to write
* Return Value: Number of bytes written
*/
uint32_t USB_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) {
uint32_t n;
LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
/* 3 clock cycles to fetch the packet length from RAM. */
delay( 5 );
LPC_USB->TxPLen = cnt;
for (n = 0; n < (cnt + 3) / 4; n++) {
LPC_USB->TxData = *((uint32_t __attribute__((packed)) *)pData);
pData += 4;
}
LPC_USB->Ctrl = 0;
WrCmdEP(EPNum, CMD_VALID_BUF);
return (cnt);
}
/*
* Get USB Last Frame Number
* Parameters: None
* Return Value: Frame Number
*/
uint32_t USB_GetFrame (void) {
uint32_t val;
WrCmd(CMD_RD_FRAME);
val = RdCmdDat(DAT_RD_FRAME);
val = val | (RdCmdDat(DAT_RD_FRAME) << 8);
return (val);
}
/*
* USB Interrupt Service Routine
*/
void USB_IRQHandler (void)
{
uint32_t disr, val, n, m;
disr = LPC_USB->DevIntSt; /* Device Interrupt Status */
LPC_USB->DevIntClr = disr;
/* Device Status Interrupt (Reset, Connect change, Suspend/Resume) */
if (disr & DEV_STAT_INT) {
WrCmd(CMD_GET_DEV_STAT);
val = RdCmdDat(DAT_GET_DEV_STAT); /* Device Status */
if (val & DEV_RST) { /* Reset */
USB_Reset();
#if USB_RESET_EVENT
USB_Reset_Event();
#endif
}
if (val & DEV_CON_CH) { /* Connect change */
#if USB_POWER_EVENT
USB_Power_Event(val & DEV_CON);
#endif
}
if (val & DEV_SUS_CH) { /* Suspend/Resume */
if (val & DEV_SUS) { /* Suspend */
USB_Suspend();
#if USB_SUSPEND_EVENT
USB_Suspend_Event();
#endif
} else { /* Resume */
USB_Resume();
#if USB_RESUME_EVENT
USB_Resume_Event();
#endif
}
}
goto isr_end;
}
#if USB_SOF_EVENT
/* Start of Frame Interrupt */
if (disr & FRAME_INT) {
LPC_USB->DevIntClr = FRAME_INT;
USB_SOF_Event();
SOFIRQCount++;
}
#endif
#if USB_ERROR_EVENT
/* NO error interrupt anymore, below code can be used
as example to get error status from command engine. */
/* Error Interrupt */
if (disr & ERR_INT) {
WrCmd(CMD_RD_ERR_STAT);
val = RdCmdDat(DAT_RD_ERR_STAT);
USB_Error_Event(val);
}
#endif
/* Endpoint's Interrupt */
if (disr & (0xFF<<1)) {
/* if any of the EP0 through EP7 is set, or bit 1 through 9 on disr */
for (n = 0; n < USB_EP_NUM; n++) { /* Check All Endpoints */
/* skip frame interrupt at bit 0 in disr */
// if (disr & ((1 << n)<<1)) {
if ((disr>>1) & (1 << n)) {
m = n >> 1;
/* clear EP interrupt by sending cmd to the command engine. */
WrCmd(CMD_SEL_EP_CLRI(n));
val = RdCmdDat(DAT_SEL_EP_CLRI(n));
if ((n & 1) == 0) { /* OUT Endpoint */
if (n == 0) { /* Control OUT Endpoint */
if (val & EP_SEL_STP) { /* Setup Packet */
if (USB_P_EP[0]) {
USB_P_EP[0](USB_EVT_SETUP);
continue;
}
}
}
if (USB_P_EP[m]) {
USB_P_EP[m](USB_EVT_OUT);
}
} else { /* IN Endpoint */
if (USB_P_EP[m]) {
USB_P_EP[m](USB_EVT_IN);
}
}
}
}
}
isr_end:
return;
}

217
firmware/src/usbuser.c Normal file
View file

@ -0,0 +1,217 @@
/*----------------------------------------------------------------------------
* U S B - K e r n e l
*----------------------------------------------------------------------------
* Name: usbuser.c
* Purpose: USB Custom User Module
* Version: V1.20
*----------------------------------------------------------------------------
* This software is supplied "AS IS" without any warranties, express,
* implied or statutory, including but not limited to the implied
* warranties of fitness for purpose, satisfactory quality and
* noninfringement. Keil extends you a royalty-free right to reproduce
* and distribute executable files created using this software for use
* on NXP Semiconductors LPC microcontroller devices only. Nothing else
* gives you the right to use this software.
*
* Copyright (c) 2009 Keil - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include "type.h"
#include "usb.h"
#include "usbcfg.h"
#include "usbhw.h"
#include "usbcore.h"
#include "usbuser.h"
#include "cdcuser.h"
#include "mscuser.h"
#include "memory.h"
/*
* USB Power Event Callback
* Called automatically on USB Power Event
* Parameter: power: On(TRUE)/Off(FALSE)
*/
#if USB_POWER_EVENT
void USB_Power_Event (uint32_t power) {
}
#endif
/*
* USB Reset Event Callback
* Called automatically on USB Reset Event
*/
#if USB_RESET_EVENT
void USB_Reset_Event (void) {
USB_ResetCore();
}
#endif
/*
* USB Suspend Event Callback
* Called automatically on USB Suspend Event
*/
#if USB_SUSPEND_EVENT
void USB_Suspend_Event (void) {
}
#endif
/*
* USB Resume Event Callback
* Called automatically on USB Resume Event
*/
#if USB_RESUME_EVENT
void USB_Resume_Event (void) {
}
#endif
/*
* USB Remote Wakeup Event Callback
* Called automatically on USB Remote Wakeup Event
*/
#if USB_WAKEUP_EVENT
void USB_WakeUp_Event (void) {
}
#endif
/*
* USB Start of Frame Event Callback
* Called automatically on USB Start of Frame Event
*/
#if USB_SOF_EVENT
void USB_SOF_Event (void) {
}
#endif
/*
* USB Error Event Callback
* Called automatically on USB Error Event
* Parameter: error: Error Code
*/
#if USB_ERROR_EVENT
void USB_Error_Event (uint32_t error) {
}
#endif
/*
* USB Set Configuration Event Callback
* Called automatically on USB Set Configuration Request
*/
#if USB_CONFIGURE_EVENT
void USB_Configure_Event (void) {
if (USB_Configuration) { /* Check if USB is configured */
/* add your code here */
}
}
#endif
/*
* USB Set Interface Event Callback
* Called automatically on USB Set Interface Request
*/
#if USB_INTERFACE_EVENT
void USB_Interface_Event (void) {
}
#endif
/*
* USB Set/Clear Feature Event Callback
* Called automatically on USB Set/Clear Feature Request
*/
#if USB_FEATURE_EVENT
void USB_Feature_Event (void) {
}
#endif
#define P_EP(n) ((USB_EP_EVENT & (1 << (n))) ? USB_EndPoint##n : NULL)
/* USB Endpoint Events Callback Pointers */
void (* const USB_P_EP[USB_LOGIC_EP_NUM]) (uint32_t event) = {
P_EP(0),
P_EP(1),
P_EP(2),
P_EP(3),
P_EP(4),
};
/*
* USB Endpoint 1 Event Callback
* Called automatically on USB Endpoint 1 Event
* Parameter: event
*/
void USB_EndPoint1 (uint32_t event) {
uint16_t temp;
static uint16_t serialState;
switch (event) {
case USB_EVT_IN:
temp = CDC_GetSerialState();
if (serialState != temp) {
serialState = temp;
CDC_NotificationIn(); /* send SERIAL_STATE notification */
}
break;
}
}
/*
* USB Endpoint 2 Event Callback
* Called automatically on USB Endpoint 2 Event
* Parameter: event
*/
void USB_EndPoint2 (uint32_t event) {
switch (event) {
case USB_EVT_OUT:
MSC_BulkOut();
break;
case USB_EVT_IN:
MSC_BulkIn();
break;
}
}
/*
* USB Endpoint 3 Event Callback
* Called automatically on USB Endpoint 3 Event
* Parameter: event
*/
void USB_EndPoint3 (uint32_t event) {
switch (event) {
case USB_EVT_OUT:
CDC_BulkOut (); /* data received from Host */
break;
case USB_EVT_IN:
CDC_BulkIn (); /* data expected from Host */
break;
}
}