ESP8266 reboot loop in "memcpy_P" function - avr
I'm trying to modify code that was initially designed for Trinket board (ATTiny85). It compiles properly for ESP8266-12E board (NodeMCU1.0). But unit is rebooting when loading image to memory.
Lines with:
memcpy_P(palette, imagePalette, 2 * 3);
Causing device to be rebooted.
I will be really greatfull if someone will advise me what should be modified to solve it? Code is taken from Github
Code:
#include <Arduino.h>
#include <Adafruit_DotStar.h>
#include <SPI.h> // Enable this line on Pro Trinket
typedef uint16_t line_t; // Bigger images OK on other boards
// CONFIGURABLE STUFF ------------------------------------------------------
#include "fire.h" // Graphics data is contained in this header file.
#define LED_DATA_PIN MOSI
#define LED_CLOCK_PIN SCK
#define SELECT_PIN 3
boolean autoCycle = false; // Set to true to cycle images by default
#define CYCLE_TIME 15 // Time, in seconds, between auto-cycle images
// -------------------------------------------------------------------------
#if defined(LED_DATA_PIN) && defined(LED_CLOCK_PIN)
// Older DotStar LEDs use GBR order. If colors are wrong, edit here.
Adafruit_DotStar strip = Adafruit_DotStar(NUM_LEDS,
LED_DATA_PIN, LED_CLOCK_PIN, DOTSTAR_BRG);
#else
Adafruit_DotStar strip = Adafruit_DotStar(NUM_LEDS, DOTSTAR_BRG);
#endif
void imageInit(void);
uint16_t readVoltage(void);
#ifdef MOTION_PIN
void sleep(void);
#endif
void setup() {
#if defined(__AVR_ATtiny85__) && (F_CPU == 16000000L)
clock_prescale_set(clock_div_1); // Enable 16 MHz on Trinket
#endif
#ifdef POWER_PIN
pinMode(POWER_PIN, OUTPUT);
digitalWrite(POWER_PIN, LOW); // Power-on LED strip
#endif
strip.begin(); // Allocate DotStar buffer, init SPI
strip.clear(); // Make sure strip is clear
strip.show(); // before measuring battery
imageInit(); // Initialize pointers for default image
#ifdef SELECT_PIN
pinMode(SELECT_PIN, INPUT_PULLUP);
#endif
}
// GLOBAL STATE STUFF ------------------------------------------------------
uint32_t lastImageTime = 0L; // Time of last image change
uint8_t imageNumber = 0, // Current image being displayed
imageType, // Image type: PALETTE[1,4,8] or TRUECOLOR
*imagePalette, // -> palette data in PROGMEM
*imagePixels, // -> pixel data in PROGMEM
palette[16][3]; // RAM-based color table for 1- or 4-bit images
line_t imageLines, // Number of lines in active image
imageLine; // Current line number in image
#ifdef SELECT_PIN
uint8_t debounce = 0; // Debounce counter for image select pin
#endif
void imageInit() { // Initialize global image state for current imageNumber
imageType = pgm_read_byte(&images[imageNumber].type);
imageLines = pgm_read_word(&images[imageNumber].lines);
imageLine = 0;
imagePalette = (uint8_t *)pgm_read_word(&images[imageNumber].palette);
imagePixels = (uint8_t *)pgm_read_word(&images[imageNumber].pixels);
if(imageType == PALETTE1) memcpy_P(palette, imagePalette, 2 * 3);
else if(imageType == PALETTE4) memcpy_P(palette, imagePalette, 16 * 3);
lastImageTime = millis(); // Save time of image init for next auto-cycle
}
void nextImage(void) {
if(++imageNumber >= NUM_IMAGES) imageNumber = 0;
imageInit();
}
// MAIN LOOP ---------------------------------------------------------------
void loop() {
uint32_t t = millis(); // Current time, milliseconds
if(autoCycle) {
if((t - lastImageTime) >= (CYCLE_TIME * 1000L)) nextImage();
// CPU clocks vary slightly; multiple poi won't stay in perfect sync.
// Keep this in mind when using auto-cycle mode, you may want to cull
// the image selection to avoid unintentional regrettable combinations.
}
#ifdef SELECT_PIN
if(digitalRead(SELECT_PIN)) { // Image select?
debounce = 0; // Not pressed -- reset counter
} else { // Pressed...
if(++debounce >= 25) { // Debounce input
nextImage(); // Switch to next image
while(!digitalRead(SELECT_PIN)); // Wait for release
// If held 1+ sec, toggle auto-cycle mode on/off
if((millis() - t) >= 1000L) autoCycle = !autoCycle;
debounce = 0;
}
}
#endif
switch(imageType) {
case PALETTE1: { // 1-bit (2 color) palette-based image
uint8_t pixelNum = 0, byteNum, bitNum, pixels, idx,
*ptr = (uint8_t *)&imagePixels[imageLine * NUM_LEDS / 8];
for(byteNum = NUM_LEDS/8; byteNum--; ) { // Always padded to next byte
pixels = pgm_read_byte(ptr++); // 8 pixels of data (pixel 0 = LSB)
for(bitNum = 8; bitNum--; pixels >>= 1) {
idx = pixels & 1; // Color table index for pixel (0 or 1)
strip.setPixelColor(pixelNum++,
palette[idx][0], palette[idx][1], palette[idx][2]);
}
}
break;
}
case PALETTE4: { // 4-bit (16 color) palette-based image
uint8_t pixelNum, p1, p2,
*ptr = (uint8_t *)&imagePixels[imageLine * NUM_LEDS / 2];
for(pixelNum = 0; pixelNum < NUM_LEDS; ) {
p2 = pgm_read_byte(ptr++); // Data for two pixels...
p1 = p2 >> 4; // Shift down 4 bits for first pixel
p2 &= 0x0F; // Mask out low 4 bits for second pixel
strip.setPixelColor(pixelNum++,
palette[p1][0], palette[p1][1], palette[p1][2]);
strip.setPixelColor(pixelNum++,
palette[p2][0], palette[p2][1], palette[p2][2]);
}
break;
}
}
strip.show(); // Refresh LEDs
delayMicroseconds(900);
if(++imageLine >= imageLines) imageLine = 0; // Next scanline, wrap around
}
And fire.h file:
// Don't edit this file! It's software-generated.
// See convert.py script instead.
#define PALETTE1 0
#define PALETTE4 1
#define PALETTE8 2
#define TRUECOLOR 3
#define NUM_LEDS 16
// fire.gif ----------------------------------------------------------------
const uint8_t PROGMEM palette00[][3] = {
{ 88, 80, 3 },
{ 88, 88, 23 },
{ 88, 34, 0 },
{ 88, 4, 0 },
{ 88, 49, 0 },
{ 88, 9, 0 },
{ 0, 0, 0 },
{ 88, 88, 10 },
{ 88, 17, 0 },
{ 16, 0, 0 },
{ 88, 1, 0 },
{ 88, 0, 0 },
{ 88, 68, 1 },
{ 33, 0, 0 },
{ 1, 0, 0 },
{ 7, 0, 0 } };
const uint8_t PROGMEM pixels00[] = {
0X66, 0X6E, 0X95, 0XC7, 0X05, 0XD9, 0XEB, 0XE6,
0X66, 0X6E, 0X93, 0XCC, 0X4A, 0X9F, 0X9B, 0XE6,
0X66, 0X66, 0X93, 0X4C, 0X8D, 0X99, 0XB9, 0XE6,
0X66, 0X6E, 0XD3, 0X42, 0X39, 0X9B, 0XB9, 0XE6,
0X66, 0X6F, 0XD5, 0X88, 0XD9, 0X9B, 0XB9, 0XE6,
0X66, 0X6F, 0XB8, 0X23, 0XDF, 0X9B, 0XBD, 0XE6,
0X66, 0XE9, 0XA8, 0X2A, 0X9E, 0X9B, 0XBD, 0XF6,
0X66, 0XE9, 0X32, 0X8B, 0XFE, 0X9B, 0XAB, 0XDE,
0X66, 0XED, 0X52, 0X5D, 0XE6, 0XFB, 0XA3, 0XB9,
0X66, 0XFB, 0X22, 0X59, 0XE6, 0XED, 0XA3, 0XAD,
0X66, 0X9A, 0X24, 0X39, 0X66, 0XEF, 0XA3, 0X3B,
0X6E, 0XF3, 0X24, 0X39, 0XE6, 0X6F, 0XD3, 0X3B,
0X66, 0X93, 0X44, 0X39, 0XE6, 0X6E, 0X93, 0X3A,
0X6E, 0X93, 0X44, 0X59, 0X66, 0X6E, 0X93, 0X5A,
0X6E, 0X93, 0X2C, 0X59, 0XE6, 0X6E, 0XD3, 0X5A,
0X66, 0X9A, 0X44, 0X8D, 0XF6, 0XEF, 0XA8, 0X8A,
0X66, 0XFA, 0X2C, 0X45, 0X9F, 0XFD, 0X52, 0X8B,
0X66, 0XED, 0X8C, 0X04, 0X5D, 0XD8, 0X44, 0X3D,
0X66, 0XE9, 0X3C, 0X77, 0XC4, 0X4C, 0XC4, 0XA9,
0X66, 0X69, 0XAC, 0X71, 0X77, 0X77, 0XC5, 0XBF,
0X66, 0XEF, 0XB2, 0X71, 0X11, 0X70, 0X2A, 0X9E,
0X66, 0X6F, 0XD8, 0X01, 0X11, 0X74, 0XA9, 0XF6,
0X66, 0X6E, 0X93, 0XC1, 0X17, 0XC3, 0XDE, 0X66,
0X6E, 0X6E, 0XFA, 0X47, 0X17, 0X2D, 0XF6, 0X66,
0X6E, 0XBF, 0XFD, 0X50, 0X7C, 0X89, 0XE6, 0X66,
0X6E, 0XBF, 0XFD, 0XA4, 0XCC, 0X39, 0XE6, 0X66,
0X6E, 0XFB, 0X9F, 0XD8, 0X44, 0X39, 0XE6, 0X66,
0X6E, 0X9B, 0XBD, 0X93, 0X22, 0X39, 0XE6, 0X66,
0X6E, 0XFB, 0XB9, 0X9D, 0X52, 0X5D, 0XE6, 0X66,
0X6E, 0XDB, 0XB9, 0XF9, 0X32, 0X8A, 0XF6, 0X66,
0X6F, 0XDB, 0XB9, 0XFF, 0XA2, 0X8A, 0X9E, 0X66,
0XED, 0XBA, 0XB9, 0XE9, 0XB8, 0X23, 0X9E, 0X66,
0X9B, 0XA3, 0XBF, 0XEE, 0XD5, 0X25, 0XDF, 0X66,
0X9A, 0X3A, 0XDF, 0X6E, 0X93, 0X28, 0XBF, 0X66,
0XB3, 0X5B, 0X96, 0X66, 0X93, 0X22, 0XAF, 0XE6,
0XB3, 0X3D, 0XE6, 0X6E, 0X93, 0X24, 0X39, 0XE6,
0XA3, 0X39, 0XE6, 0X66, 0X93, 0X42, 0X39, 0XE6,
0XA5, 0X39, 0XE6, 0X6E, 0X93, 0X44, 0X39, 0XE6,
0XA5, 0X3D, 0XE6, 0X66, 0XD5, 0X44, 0XA9, 0X66,
0XA8, 0X8A, 0X96, 0X6F, 0XD2, 0X44, 0XAF, 0X66,
0XB8, 0X25, 0XD9, 0XFD, 0X3C, 0XC8, 0XAF, 0XE6,
0XD5, 0X44, 0X5D, 0XD3, 0XC0, 0X08, 0XDE, 0X66,
0X9A, 0X20, 0XC4, 0X4C, 0X77, 0XC3, 0XDE, 0X66,
0XFB, 0X8C, 0X77, 0X71, 0X71, 0X43, 0XFE, 0X66,
0XE9, 0XA2, 0X01, 0X11, 0X17, 0X4B, 0XF6, 0X66,
0X6E, 0XDA, 0X47, 0X11, 0X17, 0X8D, 0XF6, 0X66,
0X66, 0XE9, 0X3C, 0X11, 0X1C, 0X39, 0XE6, 0X66,
0X66, 0X6F, 0XD2, 0X71, 0X74, 0XAF, 0XEE, 0X66 };
typedef struct {
uint8_t type; // PALETTE[1,4,8] or TRUECOLOR
line_t lines; // Length of image (in scanlines)
const uint8_t *palette; // -> PROGMEM color table (NULL if truecolor)
const uint8_t *pixels; // -> Pixel data in PROGMEM
} image;
const image PROGMEM images[] = {
{ PALETTE4 , 48, (const uint8_t *)palette00, pixels00 }
};
#define NUM_IMAGES (sizeof(images) / sizeof(images[0]))
Error code: (I have added Serial.Print information before each line of code that way I know there is someting with memcpy_P)
Loading pgm_read_byte... OK !
Loading pgm_read_word... OK !
Loading PALETTE1 memcpy_P...
Exception (28):
epc1=0x40202fda epc2=0x00000000 epc3=0x00000000 excvaddr=0x000078ec depc=0x00000000
ctx: cont
sp: 3ffef830 end: 3ffefa40 offset: 01a0
>>>stack>>>
3ffef9d0: 3ffe8910 3ffee7d0 00000001 402022d6
3ffef9e0: 00000000 00000001 3ffee9ec 3ffe8910
3ffef9f0: 3ffee7c4 3ffe88ec 3ffee9ec 40201ff9
3ffefa00: 0001c200 0000001c 3ffee7d0 3ffeea10
3ffefa10: 3fffdad0 00000000 3ffee7d0 40202051
3ffefa20: feefeffe feefeffe 3ffeea08 40202d60
3ffefa30: feefeffe feefeffe 3ffeea20 4010070c
<<<stack<<<
Decoded error with avr decoder:
Exception 28: LoadProhibited: A load referenced a page mapped with an attribute that does not permit loads
Decoding 6 results
0x40202fda: pgm_read_byte_inlined at C:\Users\Rafal\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/pgmspace.h line 104
0x402022d6: Adafruit_DotStar::sw_spi_out(unsigned char) at D:\Dropbox\ArduinoLib\libraries\Adafruit_DotStar/Adafruit_DotStar.cpp line 40
0x40201ff9: imageInit() at D:\Dropbox\ArduinoLib\sketch_nov16b/sketch_nov16b.ino line 167
0x40202051: setup at D:\Dropbox\ArduinoLib\sketch_nov16b/sketch_nov16b.ino line 125
0x40202d60: loop_wrapper at C:\Users\Rafal\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/core_esp8266_main.cpp line 57
0x4010070c: cont_norm at C:\Users\Rafal\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.4.0-rc2\cores\esp8266/cont.S line 109
BTW. I have tried multiple versions of boards 2.3.0, 2.4.0 RC1 and RC2.
I was able to get the adafruit code you posted above working with ESP8266 by deleting all of the instances of PROGMEM from the sketch. Just use find and replace function in arduino and delete all progmem and replace with nothing. Then replace imageinit with the one below from the supernova sketch. It does work but it stores all the patterns in working memory, not in flash. I am now trying to get patterns stored in flash so more patterns can be stored.
void imageInit() { // Initialize global image state for current imageNumber
imageType = images[imageNumber].type;
imageLines = images[imageNumber].lines;
imageLine = 0;
imagePalette = (uint8_t *)images[imageNumber].palette;
imagePixels = (uint8_t *)images[imageNumber].pixels;
// 1- and 4-bit images have their color palette loaded into RAM both for
// faster access and to allow dynamic color changing. Not done w/8-bit
// because that would require inordinate RAM (328P could handle it, but
// I'd rather keep the RAM free for other features in the future).
if(imageType == PALETTE1) memcpy_P(palette, imagePalette, 2 * 3);
else if(imageType == PALETTE4) memcpy_P(palette, imagePalette, 16 * 3);
lastImageTime = millis(); // Save time of image init for next auto-cycle
}
Related
How to generate a variable length random number in Go
I'm trying to generate a random integer with variable length in Go but I always get the number filling the total length. Here's my code: package main import ( "fmt" "math/big" "crypto/rand" ) const ResultsPerPage = 30 var ( total = new(big.Int).SetBytes([]byte{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x40, }) pages = new(big.Int).Div(total, big.NewInt(ResultsPerPage)) random *big.Int err error ) func main() { fmt.Println(pages) fmt.Println(randomString(pages)) } func randomString(l *big.Int) string { random, err = rand.Int(rand.Reader, l) fmtrandom := fmt.Sprint(random) return string(fmtrandom) } Outputs 3859736307910539847452366166956263595094585475969163479420172104717272049811 3479662380009045046388212253547512051795238437604387552617121977169155584415 Code sample: https://play.golang.org/p/HxAb6Rs_Uj Any help is appreciated. Thank you.
If I understand correctly, the issue you're having is that the random number appears to always have the same number of digits as the maximum allowed value, right? When I run the code, this is not the case. Here's an output I just observed: 3859736307910539847452366166956263595094585475969163479420172104717272049811 65719900872761032562423535702578352960653752260368991759410130265294153783 In the playground, I believe the random seed and clock time are fixed, so you'll see the same result repeatedly. But running locally, I see the expected variation in the length of the output. UPDATE You may wonder why you can run this code a bunch of times and observe that the length of the random number is very often close to the length of the maximum value. A little math explains this. Let's imagine we're picking a number between 0 and 999. How many numbers in that range have: 3 digits? 900 (100-999) 2 digits? 90 (10-99) 1 digit? 10 (0-9) Similarly, with your very large maximum value, most of the numbers that can be picked will be very close to that maximum length. It will be rare to see a number two digits short of that length. (You should see them on the order of 1% of the time.)
CreateFile Failed: 5
I'm new in windows driver. I downloaded this sample and fixed nothing but a report descriptor like this. HID_REPORT_DESCRIPTOR G_DefaultReportDescriptor[] = { 0x06, 0x00, 0xFF, // USAGE_PAGE (Vender Defined Usage Page) 0x09, 0x01, // USAGE (Vendor Usage 0x01) 0xA1, 0x01, // COLLECTION (Application) 0x85, CONTROL_FEATURE_REPORT_ID, // REPORT_ID (1) 0x09, 0x01, // USAGE (Vendor Usage 0x01) 0x15, 0x00, // LOGICAL_MINIMUM(0) 0x26, 0xff, 0x00, // LOGICAL_MAXIMUM(255) 0x75, 0x08, // REPORT_SIZE (0x08) //0x95,FEATURE_REPORT_SIZE_CB, // REPORT_COUNT 0x96, (FEATURE_REPORT_SIZE_CB & 0xff), (FEATURE_REPORT_SIZE_CB >> 8), // REPORT_COUNT 0xB1, 0x00, // FEATURE (Data,Ary,Abs) 0x09, 0x01, // USAGE (Vendor Usage 0x01) 0x75, 0x08, // REPORT_SIZE (0x08) //0x95,INPUT_REPORT_SIZE_CB, // REPORT_COUNT 0x96, (INPUT_REPORT_SIZE_CB & 0xff), (INPUT_REPORT_SIZE_CB >> 8), // REPORT_COUNT 0x81, 0x00, // INPUT (Data,Ary,Abs) 0x09, 0x01, // USAGE (Vendor Usage 0x01) 0x75, 0x08, // REPORT_SIZE (0x08) //0x95,OUTPUT_REPORT_SIZE_CB, // REPORT_COUNT 0x96, (OUTPUT_REPORT_SIZE_CB & 0xff), (OUTPUT_REPORT_SIZE_CB >> 8), // REPORT_COUNT 0x91, 0x00, // OUTPUT (Data,Ary,Abs) 0xC0, // END_COLLECTION }; to HID_REPORT_DESCRIPTOR G_DefaultReportDescriptor[] = { 0x05,0x01, // USAGE_PAGE (Generic Desktop) 0x09,0x02, // USAGE (Mouse) 0xA1,0x01, // COLLECTION (Application) 0x85,0x01, // REPORT_ID (1) 0x09,0x01, // USAGE (Pointer) 0xA1,0x00, // COLLECTION (Physical) 0x05,0x09, // USAGE Page (Buttons) 0x19,0x01, // USAGE Minimum (01) 0x29,0x03, // USAGE Maximum (03) 0x15,0x00, // LOGICAL_MINIMUM(0) 0x25,0x01, // LOGICAL_MAXIMUM(1) 0x95,0x03, // REPORT_COUNT (3) 0x75,0x01, // REPORT_SIZE (1) 0x81,0x02, // Input (Data, Variable, Absolute) 0x95,0x01, // REPORT_COUNT (1) 0x75,0x05, // REPORT_SIZE (5) 0x81,0x03, // Input (Constant) 0x05,0x01, // USAGE_PAGE (Generic Desktop) 0x09,0x30, // Usage (X) 0x09,0x31, // Usage (Y) 0x15,0x81, // LOGICAL_MINIMUM(-127) 0x25,0x7F, // LOGICAL_MAXIMUM(127) 0x75,0x08, // REPORT_SIZE (8) 0x95,0x02, // REPORT_COUNT (2) 0x81,0x06, // Input (Data, Variable, Relative) 0xC0, // END_COLLECTION 0xC0 // END_COLLECTION }; The results: 1. Successfully installed as a HID mouse. 2. Running testApp, CreateFile Failed like this. ....looking for our HID device Error: CreateFile failed: 5 Failure: Could not find our HID device Please help me. I couldn't figure out why this happened.
Mifare read APDU command recived 63 00
All! I'm trying to read data from mifare card 1k. to get ID I send: 0xFF 0xCA 0x00 0x00 0x00 Recive: 0x00 0x00 0x00 0x00 0x00 0x00 - ??? it's normal? to load auth key to reader I send: 0xFF 0x82 0x00 0x00 0x06 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF Recive: 90 00 - it's ok to authenticate in block 01 I send: 0xFF 0x86 0x00 0x00 0x05 0x01 0x00 0x01 0x60 0x00 Recive: 90 00 - it's ok to read data from block 01 I send: 0xFF 0xB0 0x00 0x01 0x0F Recive: 63 00 - how a understand it's authentication error I can't understand - why? My code: #include "stdafx.h" #include "Winscard.h" LPTSTR pmszReaders = NULL; LPTSTR pmszCards = NULL; LPTSTR pReader; LPTSTR pCard; LONG lReturn, lReturn2; DWORD cch = SCARD_AUTOALLOCATE; SCARDCONTEXT hSC; SCARD_READERSTATE readerState; LPCTSTR readerName = L"ACS ACR1222 1S Dual Reader 0"; SCARDHANDLE hCardHandle; DWORD dwAP; BYTE pbRecv[50]; DWORD dwRecv; BYTE cmdGetData[] = {0xFF, 0xCA, 0x00, 0x00, 0x00}; BYTE cmdLoadKey[] = {0xFF, 0x82, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; BYTE cmdAuthBlock01[] = {0xFF, 0x86, 0x00, 0x00, 0x05, 0x01, 0x00, 0x01, 0x60, 0x00}; BYTE cmdReadBlock01[] = {0xFF, 0xB0, 0x00, 0x01, 0x0F}; int _tmain(int argc, _TCHAR* argv[]) { lReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hSC); if ( SCARD_S_SUCCESS != lReturn ) printf("Failed SCardEstablishContext\n"); else { lReturn = SCardListReaders(hSC, NULL, (LPTSTR)&pmszReaders, &cch ); if (lReturn != SCARD_S_SUCCESS) { printf("Failed SCardListReaders\n"); } else { pReader = pmszReaders; while ( '\0' != *pReader ) { printf("Reader: %S\n", pReader ); pReader = pReader + wcslen((wchar_t *)pReader) + 1; } } memset(&readerState,0,sizeof(readerState)); readerState.szReader = pmszReaders; lReturn = SCardConnect( hSC, pmszReaders, SCARD_SHARE_EXCLUSIVE, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &hCardHandle, &dwAP ); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardConnect\n"); system("pause"); exit(1); } else { printf("Success SCardConnect\n"); switch ( dwAP ) { case SCARD_PROTOCOL_T0: printf("Active protocol T0\n"); break; case SCARD_PROTOCOL_T1: printf("Active protocol T1\n"); break; case SCARD_PROTOCOL_UNDEFINED: default: printf("Active protocol unnegotiated or unknown\n"); break; } } lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdGetData, sizeof(cmdGetData), NULL, pbRecv, &dwRecv); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardTransmit\n"); } else { printf("Success SCardTransmit\n"); printf("Read %u bytes\n", dwRecv); for(byte i=0;i<dwRecv;i++) { printf("%x ", pbRecv[i]); } printf("\n"); } lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdLoadKey, sizeof(cmdLoadKey), NULL, pbRecv, &dwRecv); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardTransmit\n"); } else { printf("Success SCardTransmit\n"); printf("Read %u bytes\n", dwRecv); for(byte i=0;i<dwRecv;i++) { printf("%x ", pbRecv[i]); } printf("\n"); } lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdAuthBlock01, sizeof(cmdAuthBlock01), NULL, pbRecv, &dwRecv); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardTransmit\n"); } else { printf("Success SCardTransmit\n"); printf("Read %u bytes\n", dwRecv); for(byte i=0;i<dwRecv;i++) { printf("%x ", pbRecv[i]); } printf("\n"); } lReturn = SCardTransmit(hCardHandle, SCARD_PCI_T1, cmdReadBlock01, sizeof(cmdReadBlock01), NULL, pbRecv, &dwRecv); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardTransmit\n"); } else { printf("Success SCardTransmit\n"); printf("Read %u bytes\n", dwRecv); for(byte i=0;i<dwRecv;i++) { printf("%x ", pbRecv[i]); } printf("\n"); } } lReturn = SCardDisconnect(hCardHandle, SCARD_LEAVE_CARD); if ( SCARD_S_SUCCESS != lReturn ) { printf("Failed SCardDisconnect\n"); } else { printf("Success SCardDisconnect\n"); } system("pause"); return 0; } Can anyone explain why i got 63 00? Thanks.
Afair your read command has to be: "0xFF, 0xB0, 0x00, BLOCK, 0x10". You send buffer length 0F - which is decimal 15 - but you have to read 16 Byte, which is 0x10. Hope this helps
In Mifare Classic 1K tags There are 16 Sectors and each Sectors contains 4 Blocks and each block contains 16 bytes. Sector 0 contains Block (0,1,2,3) Sector 1 contains Block (4,5,6,7) Sector 2 contains Block (8,9,10,11) Sector 3 contains Block (12,13,14,15).... Before Reading or writing from a block You must have to Authenticate its corresponding Sector using Key A or Key B of that sector. When Authentication is complete then you can read or write. using this command you can authenticate sector 0 using KEY A(60) byte[] authenticationByte = new byte[10]; authenticationByte = new byte[] { (byte) 0xFF, (byte) 0x86, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x00,(byte) 0x00, (byte) 0x04, (byte) 0x60,(byte) 0x00 }; When Authentication is succes then you will get 90 00. That is Success message. Else response is 63 00 , that means authentication failed. When Authentication complete then you can read block (0,1,2,3) cause sector 0 contains 4 block and those are block (0,1,2,3). Here your problem is you are authenticating Sector 1 but trying to read data from Sector 0's blocks. For more details you can read this Answer. Sorry for bad English
crc16 implementation java
I am having problems with calculating CRC-16 implementation of a byte array in java. Basically I am trying to send bytes to a RFID that starts writing to a tag. I can see the checksum value of array by looking tcpdump command on mac. But my goal is to generate it by myself. Here is my byte array which should generate 0xbe,0xd9: byte[] bytes = new byte[]{(byte) 0x55,(byte) 0x08,(byte) 0x68, (byte) 0x14, (byte) 0x93, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x11}; 0x55 is the header. As the documentation says it will be excluded. Whenever I try this array on java (with 0xbe,0xd9), RFID works. My problem is the generating of those checksum values. I searched almost entire web but no chance. I couldn't find any algorithm that produces 0xbe,0xd9. Any idea is most welcome for me. Thanks in advance. edit: here is the protocol that provided with rfid
I'm not really sure if this is the correct translation in Java of the C crc16 algorithm.... but it shows the correct result for your example! Please compare other results with Mac's CRC16 and stress-test it before using it. public class Crc16 { public static void main(String... a) { byte[] bytes = new byte[] { (byte) 0x08, (byte) 0x68, (byte) 0x14, (byte) 0x93, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x13, (byte) 0x50, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x22, (byte) 0x09, (byte) 0x11 }; byte[] byteStr = new byte[4]; Integer crcRes = new Crc16().calculate_crc(bytes); System.out.println(Integer.toHexString(crcRes)); byteStr[0] = (byte) ((crcRes & 0x000000ff)); byteStr[1] = (byte) ((crcRes & 0x0000ff00) >>> 8); System.out.printf("%02X\n%02X", byteStr[0],byteStr[1]); } int calculate_crc(byte[] bytes) { int i; int crc_value = 0; for (int len = 0; len < bytes.length; len++) { for (i = 0x80; i != 0; i >>= 1) { if ((crc_value & 0x8000) != 0) { crc_value = (crc_value << 1) ^ 0x8005; } else { crc_value = crc_value << 1; } if ((bytes[len] & i) != 0) { crc_value ^= 0x8005; } } } return crc_value; } }
There is a CRC16 implementation in the Java runtime (rt.jar) already. Please see grepcode for the source. You will probably be able to see it in your IDE if you search for CRC16:
Maybe are you looking for this? Crc16 in java I use the same array (variable "table") in this method: public Integer computeCrc16(byte[] data) { int crc = 0x0000; for (byte b : data) { crc = (crc >>> 8) ^ table[((crc ^ b) & 0xff)]; } return (int) crc; }
if you want ASCII character then change byte[] bytes="02303131313233343031303345303903".getBytes(); Below is correct answer for HEX input , byte[] bytes = hexStringToByteArray("02303131313233343031303345303903"); public class CRC16 { public static void main(String[] args) { int[] table = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, }; byte[] bytes = hexStringToByteArray("02303131313233343031303345303903"); // for HEX int crc16 = 0x0000; for (byte b : bytes) { crc16=table[(crc16 ^ b) & 0xff] ^ (crc16 >> 8); } crc16= crc16 & 0xFFFF; System.out.println("CRC16 = " +Integer.toHexString(crc16)); } public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)+ Character.digit(s.charAt(i+1), 16)); } return data; } }
Binding numeric keypad keys with Emacs 24 and OS/X
I'm currently trying out the Git HEAD version of Emacs 24 on OS/X as described in this article: http://www.viget.com/extend/emacs-24-rails-development-environment-from-scratch-to-productive-in-5-minu/ I'd like to bind some of the Macintosh extended keyboard numeric keypad keys to Emacs functions, but it doesn't seem to be working. When I do a "c-h k" to check the key details the key presses are not recognized. Ditto if I refer to them in a (global-set-key (kbd "kp-minus") ...) setting. Is this an issue with using the development version of Emacs 24 or is it something about the Macintosh keyboard hardware and how Emacs sees it? Can anyone advise on the best way to go about this? Thanks in advance, Stu
I had the same issue with the keypad keys building emacs 24. The problem is the same with emacs 23. I patched the emacs 24 code as follows to correct the problem. Not sure this is a good solution but it works well enough for me. index 91f0cbb..d537ee3 100644 --- a/src/nsterm.m +++ b/src/nsterm.m ## -87,6 +87,7 ## static unsigned convert_ns_to_X_keysym[] = NSBeginFunctionKey, 0x58, NSSelectFunctionKey, 0x60, NSPrintFunctionKey, 0x61, + NSClearLineFunctionKey, 0x0B, NSExecuteFunctionKey, 0x62, NSInsertFunctionKey, 0x63, NSUndoFunctionKey, 0x65, ## -134,6 +135,35 ## static unsigned convert_ns_to_X_keysym[] = 0x1B, 0x1B /* escape */ }; +static unsigned convert_nskeypad_to_X_keysym[] = +{ + /* Arrow keys are both function and keypad keys */ + NSLeftArrowFunctionKey, 0x51, + NSUpArrowFunctionKey, 0x52, + NSRightArrowFunctionKey, 0x53, + NSDownArrowFunctionKey, 0x54, + + 0x41, 0xAE, /* KP_Decimal */ + 0x43, 0xAA, /* KP_Multiply */ + 0x45, 0xAB, /* KP_Add */ + 0x4B, 0xAF, /* KP_Divide */ + 0x4E, 0xAD, /* KP_Subtract */ + 0x51, 0xBD, /* KP_Equal */ + 0x52, 0xB0, /* KP_0 */ + 0x53, 0xB1, /* KP_1 */ + 0x54, 0xB2, /* KP_2 */ + 0x55, 0xB3, /* KP_3 */ + 0x56, 0xB4, /* KP_4 */ + 0x57, 0xB5, /* KP_5 */ + 0x58, 0xB6, /* KP_6 */ + 0x59, 0xB7, /* KP_7 */ + 0x5B, 0xB8, /* KP_8 */ + 0x5C, 0xB9, /* KP_9 */ + + // The enter key is on the keypad but modifier isnt set + NSEnterCharacter, 0x8D +}; + static Lisp_Object Qmodifier_value; Lisp_Object Qalt, Qcontrol, Qhyper, Qmeta, Qsuper, Qnone; ## -1924,13 +1954,33 ## ns_convert_key (unsigned code) unsigned keysym; /* An array would be faster, but less easy to read. */ for (keysym = 0; keysym < last_keysym; keysym += 2) - if (code == convert_ns_to_X_keysym[keysym]) - return 0xFF00 | convert_ns_to_X_keysym[keysym+1]; + + if (code == convert_ns_to_X_keysym[keysym]) { + return 0xFF00 | convert_ns_to_X_keysym[keysym+1]; + } return 0; /* if decide to use keyCode and Carbon table, use this line: return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */ } +static unsigned +ns_convert_keypad (unsigned code) +/* -------------------------------------------------------------------------- + Internal call used by NSView-keyDown. + -------------------------------------------------------------------------- */ +{ + const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym) + / sizeof (convert_nskeypad_to_X_keysym[0])); + unsigned keysym; + /* An array would be faster, but less easy to read. */ + for (keysym = 0; keysym < last_keysym; keysym += 2) { + if (code == convert_nskeypad_to_X_keysym[keysym]) { + return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1]; + } + } + return 0; +} + char * x_get_keysym_name (int keysym) ## -4503,10 +4553,10 ## ns_term_shutdown (int sig) Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (emacsframe); int code; unsigned fnKeysym = 0; - int flags; static NSMutableArray *nsEvArray; static BOOL firstTime = YES; int left_is_none; + unsigned int flags = [theEvent modifierFlags]; NSTRACE (keyDown); ## -4550,9 +4600,13 ## ns_term_shutdown (int sig) code = ([[theEvent charactersIgnoringModifiers] length] == 0) ? 0 : [[theEvent charactersIgnoringModifiers] characterAtIndex: 0]; /* (Carbon way: [theEvent keyCode]) */ + /* is it a "function key"? */ - fnKeysym = ns_convert_key (code); + if (code < 0x00ff && (flags & NSNumericPadKeyMask) ) + fnKeysym = ns_convert_keypad([theEvent keyCode]); + else + fnKeysym = ns_convert_key(code); if (fnKeysym) { /* COUNTERHACK: map 'Delete' on upper-right main KB to 'Backspace', ## -4565,7 +4619,6 ## ns_term_shutdown (int sig) /* are there modifiers? */ emacs_event->modifiers = 0; - flags = [theEvent modifierFlags]; if (flags & NSHelpKeyMask) emacs_event->modifiers |= hyper_modifier;
I tried this with an older Emacs: This is GNU Emacs 22.2.1 (powerpc-apple-darwin9.5.0, GTK+ Version 2.10.13) Built from the ports collection with +gtk +x11 and used with the X11 server XQuartz 2.1.6 (xorg-server 1.4.2-apple33), when I look with C-h lI get <kp-0> ... <kp-9> for the numbers. and <kp-enter> <kp-subtract> <kp-multiply> <kp-divide> <kp-equal> For the other keys. I'd suggest to build the latest Emacs from MacPorts with the options +gtk and +x11. Then I'd get the latest XQuartz and run Emacs over X11 (I prefer this to the more native builds because then Emacs always behaves the same regardless if it runs remotely on another OS (usually via ssh -Y) or locally. I'll upgrade my ports to the latest Emacs next week and add the result for these also.
The problem is exclusive to the Cocoa variant of emacs. The problem did not exist in the Carbon version, which is emacs22. I updated the patch I posted above, which now works better. It will likely work with the Emacs23 code base using XCode 3. If you are using XCode 4, like me you will need to use the Emacs24 code base which is currently only available in the GIT repository. Here is a very nice description on building Emacs24 via XCode 4 [http://mikbe.tk/2011/04/18/build-emacs-with-xcode-4/][1]
Here's an Emacs 23.3 translation of the Emacs 24 patch M. D. Marchionna's posted on this page. --- nsterm-orig.m 2011-11-13 17:51:47.000000000 -0500 +++ nsterm.m 2011-11-13 17:39:56.000000000 -0500 ## -87,6 +87,7 ## NSBeginFunctionKey, 0x58, NSSelectFunctionKey, 0x60, NSPrintFunctionKey, 0x61, + NSClearLineFunctionKey, 0x0B, NSExecuteFunctionKey, 0x62, NSInsertFunctionKey, 0x63, NSUndoFunctionKey, 0x65, ## -134,6 +135,33 ## 0x1B, 0x1B /* escape */ }; +static unsigned convert_nskeypad_to_X_keysym[] = +{ + /* Arrow keys are both function and keypad keys */ + NSLeftArrowFunctionKey, 0x51, + NSUpArrowFunctionKey, 0x52, + NSRightArrowFunctionKey, 0x53, + NSDownArrowFunctionKey, 0x54, + + 0x41, 0xAE, /* KP_Decimal */ + 0x43, 0xAA, /* KP_Multiply */ + 0x45, 0xAB, /* KP_Add */ + 0x4B, 0xAF, /* KP_Divide */ + 0x4E, 0xAD, /* KP_Subtract */ + 0x51, 0xBD, /* KP_Equal */ + 0x52, 0xB0, /* KP_0 */ + 0x53, 0xB1, /* KP_1 */ + 0x54, 0xB2, /* KP_2 */ + 0x55, 0xB3, /* KP_3 */ + 0x56, 0xB4, /* KP_4 */ + 0x57, 0xB5, /* KP_5 */ + 0x58, 0xB6, /* KP_6 */ + 0x59, 0xB7, /* KP_7 */ + 0x5B, 0xB8, /* KP_8 */ + 0x5C, 0xB9, /* KP_9 */ + // The enter key is on the keypad but modifier isnt set + NSEnterCharacter, 0x8D +}; /* Lisp communications */ Lisp_Object ns_input_file, ns_input_font, ns_input_fontsize, ns_input_line; ## -1842,6 +1870,23 ## return code > 0xff ? 0 : 0xFF00 | ns_keycode_to_xkeysym_table[code]; */ } +static unsigned +ns_convert_keypad (unsigned code) +/* -------------------------------------------------------------------------- + Internal call used by NSView-keyDown. + -------------------------------------------------------------------------- */ +{ + const unsigned last_keysym = (sizeof (convert_nskeypad_to_X_keysym) + / sizeof (convert_nskeypad_to_X_keysym[0])); + unsigned keysym; + /* An array would be faster, but less easy to read. */ + for (keysym = 0; keysym < last_keysym; keysym += 2) { + if (code == convert_nskeypad_to_X_keysym[keysym]) { + return 0xFF00 | convert_nskeypad_to_X_keysym[keysym+1]; + } + } + return 0; +} char * x_get_keysym_name (int keysym) ## -4349,7 +4394,7 ## struct ns_display_info *dpyinfo = FRAME_NS_DISPLAY_INFO (emacsframe); int code; unsigned fnKeysym = 0; - int flags; + unsigned int flags = [theEvent modifierFlags]; static NSMutableArray *nsEvArray; static BOOL firstTime = YES; ## -4397,6 +4442,9 ## /* (Carbon way: [theEvent keyCode]) */ /* is it a "function key"? */ + if (code < 0x00ff && (flags & NSNumericPadKeyMask) ) + fnKeysym = ns_convert_keypad([theEvent keyCode]); + else fnKeysym = ns_convert_key (code); if (fnKeysym) { ## -4410,8 +4458,6 ## /* are there modifiers? */ emacs_event->modifiers = 0; - flags = [theEvent modifierFlags]; - if (flags & NSHelpKeyMask) emacs_event->modifiers |= hyper_modifier;