diff --git a/chipset/em9301/EM9301_Patch_V0x0A.c b/chipset/em9301/EM9301_Patch_V0x0A.c new file mode 100644 index 0000000000..3c36203b29 --- /dev/null +++ b/chipset/em9301/EM9301_Patch_V0x0A.c @@ -0,0 +1,144 @@ +/* + * EM9301_Patch_V0x0A.c + * + * Created on: 14.02.2020 + * Author: sven + */ + +#define BTSTACK_FILE__ "EM9301_Patch_V0x0A.c" + +#include + +//EM9301 patch version pram_2kx22_v0x0A_patch +const uint8_t EMPatchArray[] = { +0xef, 0xff, 0xfe, 0xf7, 0x3b, 0xff, 0xfc, 0xf7, 0xd9, 0xf8, 0xd8, 0xf8, 0xc8, 0xf8, 0xc7, 0xf8, 0x5a, 0xf8, 0x59, 0xf8, 0x58, 0xf8, 0x57, 0xf8, 0x56, 0xf8, 0x55, 0xf8, 0x54, 0xf8, 0x53, 0xf8, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, +0xf3, 0xa7, 0xff, 0xa6, 0xe9, 0xff, 0xff, 0xdf, 0x1f, 0xaa, 0xec, 0xff, 0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xfe, 0xaf, 0xff, 0xaf, 0x00, 0xff, 0xff, 0xaf, 0x01, 0xff, 0xf3, 0xab, 0x0e, 0x0e, 0x33, 0x0b, 0x0e, 0x33, 0x03, 0x03, 0x03, 0x03, 0x16, 0x0e, 0x02, 0x0e, 0x02, 0x04, +0xbf, 0x2b, 0xff, 0x1b, 0xe0, 0xff, 0x29, 0xf3, 0xc4, 0xaf, 0xf7, 0xab, 0xef, 0xbb, 0xf7, 0xbb, 0x03, 0x2a, 0x97, 0xab, 0xbf, 0x2b, 0xff, 0x1b, 0xcb, 0xff, 0xff, 0xdf, 0xfc, 0xef, 0x03, 0x2a, 0x0e, 0x0e, 0x32, 0x3a, 0x0c, 0x04, 0x0e, 0x01, 0x0e, 0x04, 0x0e, 0x0e, 0x32, 0x0b, 0x00, 0x0e, +0x97, 0xab, 0xbf, 0x2b, 0xff, 0x1b, 0xd2, 0xff, 0xf7, 0xab, 0x10, 0x2b, 0xf7, 0xbb, 0x98, 0xab, 0xfb, 0x1b, 0xb0, 0xff, 0x98, 0xab, 0xc0, 0xff, 0x99, 0x7f, 0x98, 0xab, 0xc3, 0xff, 0xfe, 0xaf, 0x04, 0x0e, 0x0e, 0x36, 0x04, 0x0e, 0x01, 0x04, 0x0e, 0x36, 0x04, 0x36, 0x00, 0x04, 0x32, 0x0e, +0x01, 0xff, 0xff, 0xab, 0xff, 0xac, 0x1f, 0xf0, 0x97, 0xff, 0xfe, 0xab, 0xff, 0xac, 0x1f, 0xf0, 0x97, 0xfe, 0xff, 0x14, 0xb0, 0xff, 0xfd, 0xab, 0xff, 0xac, 0x1f, 0xf0, 0x97, 0xfd, 0xff, 0x14, 0x02, 0x0e, 0x0e, 0x3a, 0x00, 0x0e, 0x0e, 0x3a, 0x00, 0x0e, 0x32, 0x0e, 0x0e, 0x3a, 0x00, 0x0e, +0xa0, 0xff, 0xfd, 0xa5, 0x01, 0xaf, 0xfe, 0x1f, 0xa8, 0xff, 0x2e, 0xf0, 0xc5, 0xaf, 0xfe, 0xab, 0x5c, 0xaf, 0xef, 0xad, 0xd4, 0xef, 0xc0, 0xaf, 0xb1, 0xaf, 0x03, 0xc4, 0x97, 0xb5, 0xfc, 0xa5, 0x36, 0x0e, 0x1e, 0x0e, 0x36, 0x3a, 0x0c, 0x0e, 0x0c, 0x0e, 0x3a, 0x0c, 0x0c, 0x02, 0x01, 0x0e, +0x01, 0xaf, 0xfe, 0x1f, 0x9a, 0xff, 0x2e, 0xf0, 0xc5, 0xaf, 0xf4, 0xab, 0xfb, 0x2b, 0xff, 0x1b, 0x82, 0xff, 0xf4, 0xfb, 0xff, 0x14, 0x91, 0xff, 0xfc, 0xaf, 0x00, 0xff, 0xfb, 0xab, 0x5c, 0xaf, 0x1e, 0x0e, 0x36, 0x3a, 0x0c, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x0e, 0x36, 0x0e, 0x02, 0x0e, 0x0c, +0xf1, 0xad, 0xd4, 0xef, 0xc0, 0xaf, 0xb1, 0xaf, 0xfc, 0xaf, 0x04, 0xcf, 0xf3, 0xaf, 0x05, 0xcf, 0x00, 0xaf, 0x06, 0xcf, 0xfd, 0xaf, 0x03, 0xcf, 0x62, 0xff, 0xf4, 0xab, 0xf7, 0x2b, 0xff, 0x1b, 0x0e, 0x3a, 0x0c, 0x0c, 0x0e, 0x02, 0x0e, 0x02, 0x1e, 0x02, 0x0e, 0x02, 0x33, 0x04, 0x0e, 0x0e, +0x7a, 0xff, 0xf4, 0xab, 0xfe, 0x2b, 0xff, 0x1b, 0x6b, 0xff, 0xf4, 0xab, 0xf7, 0x2b, 0xfb, 0xa4, 0xff, 0x1b, 0x74, 0xff, 0xfa, 0xa4, 0xf4, 0xf6, 0xfe, 0xab, 0x5c, 0xaf, 0xef, 0xad, 0xd4, 0xef, 0x32, 0x04, 0x0e, 0x0e, 0x36, 0x04, 0x0e, 0x0e, 0x0e, 0x32, 0x0e, 0x00, 0x0e, 0x0c, 0x0e, 0x3a, +0xc0, 0xaf, 0xb1, 0xaf, 0x03, 0xc4, 0x62, 0xff, 0xf4, 0xef, 0xfe, 0xab, 0x5c, 0xaf, 0x00, 0xad, 0xd4, 0xef, 0xc0, 0xaf, 0xb1, 0xaf, 0xfe, 0xaf, 0x03, 0xcf, 0x97, 0xb5, 0xff, 0xdf, 0x01, 0x2a, 0x0c, 0x0c, 0x02, 0x33, 0x00, 0x0e, 0x0c, 0x0e, 0x3a, 0x0c, 0x0c, 0x0e, 0x02, 0x01, 0x0b, 0x0e, +0x02, 0x2a, 0xfb, 0xab, 0xdf, 0x2b, 0xff, 0x1b, 0x57, 0xff, 0xfb, 0xdf, 0x02, 0x2a, 0x70, 0xf4, 0xfc, 0xab, 0xfb, 0x2b, 0xff, 0x1b, 0x50, 0xff, 0xfc, 0xfb, 0x01, 0x2a, 0xd1, 0xfe, 0xfc, 0xab, 0x0e, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x0e, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x0e, 0x3a, 0x04, +0xf7, 0x2b, 0xff, 0x1b, 0x49, 0xff, 0xfc, 0xf7, 0x01, 0x2a, 0x67, 0xf3, 0xfc, 0xab, 0xef, 0x2b, 0xff, 0x1b, 0x61, 0xff, 0xfc, 0xef, 0x01, 0x2a, 0x68, 0xf3, 0x61, 0xff, 0x02, 0xaf, 0x01, 0xa9, 0x0e, 0x0e, 0x36, 0x00, 0x0e, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x0e, 0x3a, 0x33, 0x16, 0x16, +0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa4, 0xff, 0xff, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x78, 0xff, 0x79, 0xff, 0x70, 0xff, 0x71, 0xff, 0x72, 0xff, 0x73, 0xff, 0x74, 0xff, 0x75, 0xff, 0x7e, 0x16, 0x16, 0x16, 0x23, 0x03, 0x0b, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, +0xff, 0x7d, 0xff, 0x7c, 0xff, 0x7b, 0x80, 0x2a, 0x40, 0x2a, 0xdf, 0xba, 0xfd, 0xab, 0xfe, 0x2b, 0xff, 0x1b, 0x23, 0xff, 0xfd, 0xfe, 0x70, 0xf5, 0xfd, 0xab, 0xfd, 0x2b, 0xff, 0x1b, 0x1d, 0xff, 0x03, 0x03, 0x03, 0x0e, 0x0e, 0x0e, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x3a, 0x04, 0x0e, 0x0e, 0x36, +0xfd, 0xfd, 0x56, 0xf5, 0xfd, 0xab, 0xef, 0x2b, 0xff, 0x1b, 0x17, 0xff, 0xfd, 0xeb, 0x03, 0xf5, 0xfd, 0xab, 0xfb, 0x2b, 0xff, 0x1b, 0xfb, 0xfe, 0x74, 0xab, 0xfe, 0x1b, 0xfd, 0xfe, 0xaf, 0xab, 0x00, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x04, 0x0e, 0x32, 0x04, +0xbf, 0x2b, 0xff, 0x1b, 0xfd, 0xfe, 0xf9, 0xa1, 0x87, 0xa0, 0x00, 0xaf, 0xfe, 0x1f, 0xfd, 0xfe, 0x2e, 0xf0, 0xc4, 0xaf, 0xfe, 0xab, 0xef, 0xad, 0xd4, 0xef, 0xc0, 0xaf, 0xb1, 0xaf, 0xfc, 0xaf, 0x0e, 0x0e, 0x32, 0x0e, 0x0e, 0x18, 0x0e, 0x32, 0x3a, 0x0c, 0x0e, 0x0e, 0x3a, 0x0c, 0x0c, 0x0e, +0x03, 0xcf, 0x97, 0xb4, 0xfd, 0xfb, 0x3c, 0xf5, 0xfd, 0xab, 0xf7, 0x2b, 0xff, 0x1b, 0xf5, 0xfe, 0xfd, 0xf7, 0x22, 0xf5, 0xfd, 0xab, 0xdf, 0x2b, 0xff, 0x1b, 0xef, 0xfe, 0xfd, 0xdf, 0x9a, 0xf4, 0x02, 0x01, 0x00, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x3a, +0xfd, 0xab, 0xbf, 0x2b, 0xff, 0x1b, 0xe9, 0xfe, 0xfd, 0xbf, 0x87, 0xf4, 0xfd, 0xab, 0x7f, 0x2b, 0xff, 0x1b, 0xe3, 0xfe, 0xfd, 0x7f, 0x86, 0xf4, 0x10, 0x2a, 0xbf, 0xba, 0x7f, 0xba, 0x01, 0xab, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x3a, 0x04, 0x0e, 0x0e, 0x36, 0x00, 0x3a, 0x0e, 0x0e, 0x0e, 0x16, +0x01, 0xac, 0x01, 0xad, 0x01, 0xae, 0x01, 0xa5, 0x01, 0xa4, 0x01, 0xa3, 0x01, 0xa2, 0x01, 0xa1, 0x01, 0xa0, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xaf, 0x01, 0xaf, 0xff, 0x1f, 0xff, 0x78, 0xff, 0x79, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x16, 0x3f, 0x03, 0x03, +0x9d, 0xab, 0xbc, 0xaf, 0xff, 0xab, 0x9c, 0xad, 0xde, 0xaf, 0xff, 0xad, 0xcc, 0x4e, 0xbb, 0x5d, 0xfc, 0x2c, 0xff, 0xab, 0x7f, 0xfb, 0xd5, 0xfd, 0xbf, 0xbc, 0xd5, 0xfd, 0x9c, 0xab, 0xfe, 0x2b, 0x04, 0x0c, 0x0e, 0x04, 0x0c, 0x0e, 0x0c, 0x0c, 0x0e, 0x0e, 0x0e, 0x32, 0x0c, 0x36, 0x04, 0x0e, +0xbe, 0xaf, 0xff, 0xad, 0xbf, 0xee, 0xff, 0x7f, 0xbf, 0xed, 0xed, 0xbf, 0x01, 0xae, 0xe0, 0xaf, 0x7f, 0xc0, 0xd1, 0xaf, 0xf3, 0xd1, 0x77, 0xb1, 0x76, 0xb0, 0x01, 0xac, 0x02, 0xab, 0xfb, 0x1b, 0x0c, 0x0e, 0x0e, 0x03, 0x0e, 0x0c, 0x16, 0x0c, 0x0e, 0x0c, 0x0e, 0x01, 0x01, 0x18, 0x18, 0x0e, +0xa6, 0xfe, 0xf9, 0x1c, 0xaa, 0xfe, 0x3e, 0xe4, 0xe3, 0xfd, 0xe2, 0x1c, 0xe4, 0xfd, 0x11, 0xe4, 0xe3, 0xfd, 0xf3, 0x1b, 0x9c, 0xfe, 0xfe, 0x1c, 0xa0, 0xfe, 0xc5, 0xec, 0xe3, 0xfd, 0xd2, 0x1c, 0x32, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x0e, 0x32, 0x3a, 0x33, 0x0e, +0xe4, 0xfd, 0xc3, 0xe3, 0xe3, 0xfd, 0xef, 0x1b, 0x8a, 0xfe, 0xfe, 0x1c, 0x96, 0xfe, 0xa9, 0xec, 0xe3, 0xfd, 0xfd, 0x1c, 0x92, 0xfe, 0xfb, 0xec, 0xe3, 0xfd, 0xfc, 0x1c, 0x8e, 0xfe, 0x16, 0xed, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xf6, 0x1c, 0xe4, 0xfd, 0xe0, 0xec, 0xe3, 0xfd, 0xeb, 0x1b, 0x84, 0xfe, 0xfa, 0x1c, 0xe4, 0xfd, 0x85, 0xe3, 0xe3, 0xfd, 0xdf, 0x1b, 0x0a, 0xfe, 0xfe, 0x1c, 0x7e, 0xfe, 0x7d, 0xec, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xfd, 0x1c, 0x7a, 0xfe, 0x61, 0xec, 0xe3, 0xfd, 0xfc, 0x1c, 0x76, 0xfe, 0x49, 0xec, 0xe3, 0xfd, 0xfa, 0x1c, 0x72, 0xfe, 0x2e, 0xec, 0xe3, 0xfd, 0xf9, 0x1c, 0x6e, 0xfe, 0xd3, 0xea, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xf8, 0x1c, 0x6a, 0xfe, 0x16, 0xea, 0xe3, 0xfd, 0xf7, 0x1c, 0x66, 0xfe, 0xfc, 0xe9, 0xe3, 0xfd, 0xf6, 0x1c, 0x62, 0xfe, 0xc0, 0xe9, 0xe3, 0xfd, 0xf5, 0x1c, 0x5e, 0xfe, 0x09, 0xfd, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xf4, 0x1c, 0x5a, 0xfe, 0x13, 0xe9, 0xe3, 0xfd, 0xf3, 0x1c, 0x56, 0xfe, 0x97, 0xfc, 0xe3, 0xfd, 0xf2, 0x1c, 0x52, 0xfe, 0x0f, 0xfc, 0xe3, 0xfd, 0xf1, 0x1c, 0x4e, 0xfe, 0x0d, 0xfa, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xf0, 0x1c, 0x4a, 0xfe, 0x12, 0xec, 0xe3, 0xfd, 0xef, 0x1c, 0x46, 0xfe, 0xd2, 0xfd, 0xe3, 0xfd, 0xee, 0x1c, 0x42, 0xfe, 0xd2, 0xeb, 0xe3, 0xfd, 0xed, 0x1c, 0x3e, 0xfe, 0x9e, 0xfd, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xec, 0x1c, 0x3a, 0xfe, 0x96, 0xf9, 0xe3, 0xfd, 0xeb, 0x1c, 0x36, 0xfe, 0xfa, 0xe4, 0xe3, 0xfd, 0xea, 0x1c, 0x32, 0xfe, 0xa0, 0xe4, 0xe3, 0xfd, 0xe9, 0x1c, 0x2e, 0xfe, 0x6c, 0xe4, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xe8, 0x1c, 0x2a, 0xfe, 0x53, 0xe3, 0xe3, 0xfd, 0xe7, 0x1c, 0x26, 0xfe, 0x19, 0xe3, 0xe3, 0xfd, 0xe6, 0x1c, 0x22, 0xfe, 0xfa, 0xe2, 0xe3, 0xfd, 0xe5, 0x1c, 0x1e, 0xfe, 0x98, 0xe2, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xe4, 0x1c, 0x1a, 0xfe, 0x1e, 0xe2, 0xe3, 0xfd, 0xe3, 0x1c, 0x16, 0xfe, 0xee, 0xea, 0xe3, 0xfd, 0xe2, 0x1c, 0x12, 0xfe, 0xdd, 0xe1, 0xe3, 0xfd, 0xe1, 0x1c, 0x0e, 0xfe, 0x9f, 0xe1, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, +0xe3, 0xfd, 0xe0, 0x1c, 0xe4, 0xfd, 0x53, 0xe1, 0xe3, 0xfd, 0x03, 0x1b, 0xe4, 0xfd, 0xff, 0x1c, 0x04, 0xfe, 0x73, 0xef, 0xe3, 0xfd, 0xfe, 0x1c, 0x00, 0xfe, 0x3b, 0xef, 0xe3, 0xfd, 0xfd, 0x1c, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, +0xfc, 0xfd, 0x17, 0xef, 0xe3, 0xfd, 0xfc, 0x1c, 0xf8, 0xfd, 0xfb, 0xee, 0xe3, 0xfd, 0xfb, 0x1c, 0xf4, 0xfd, 0x4b, 0xee, 0xe3, 0xfd, 0xfa, 0x1c, 0xf0, 0xfd, 0xf5, 0xed, 0xe3, 0xfd, 0xf9, 0x1c, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, +0xec, 0xfd, 0xd5, 0xed, 0xe3, 0xfd, 0xf8, 0x1c, 0xe8, 0xfd, 0x9f, 0xed, 0xe3, 0xfd, 0xf7, 0x1c, 0xe4, 0xfd, 0x50, 0xed, 0xe3, 0xfd, 0x31, 0xed, 0x9d, 0xab, 0xbc, 0xaf, 0xff, 0xab, 0x9c, 0xad, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x0e, 0x32, 0x3a, 0x33, 0x3a, 0x04, 0x0c, 0x0e, 0x04, +0xde, 0xaf, 0xff, 0xad, 0xcc, 0x4e, 0xbb, 0x5d, 0xfc, 0x2c, 0xff, 0xab, 0x7f, 0xfb, 0xd5, 0xfd, 0xbf, 0xbc, 0xc1, 0xfe, 0x01, 0xa9, 0x01, 0xa8, 0xff, 0xff, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0x0c, 0x0e, 0x0c, 0x0c, 0x0e, 0x0e, 0x0e, 0x32, 0x0c, 0x32, 0x16, 0x16, 0x23, 0x03, 0x03, 0x03, +0x2e, 0xf0, 0xc5, 0xaf, 0xfb, 0xab, 0xef, 0xae, 0xdf, 0xad, 0x0a, 0xf0, 0xc2, 0xaf, 0xb3, 0xaf, 0x6f, 0xaf, 0xfe, 0x1f, 0xc2, 0xfd, 0x67, 0xaf, 0xb1, 0xfd, 0x63, 0xaf, 0xfe, 0x1f, 0xba, 0xfd, 0x3a, 0x0c, 0x0e, 0x0e, 0x0e, 0x3a, 0x0c, 0x0c, 0x04, 0x0e, 0x32, 0x04, 0x32, 0x04, 0x0e, 0x32, +0x62, 0xaf, 0x0f, 0x1f, 0xba, 0xfd, 0x60, 0xaf, 0xb1, 0xfd, 0x63, 0xaf, 0xfe, 0x1f, 0xae, 0xfd, 0x62, 0xaf, 0x0f, 0x1f, 0xae, 0xfd, 0x52, 0xaf, 0xfe, 0x1f, 0xae, 0xfd, 0xf3, 0xaf, 0x06, 0xdf, 0x04, 0x0e, 0x36, 0x04, 0x32, 0x04, 0x0e, 0x32, 0x04, 0x0e, 0x32, 0x04, 0x0e, 0x32, 0x0e, 0x02, +0xa3, 0xfd, 0x73, 0xff, 0xfb, 0xa1, 0x5e, 0xa0, 0xff, 0xab, 0xff, 0xaf, 0x01, 0x4f, 0xbb, 0x1f, 0xe4, 0x1b, 0xaa, 0xfd, 0xff, 0xaf, 0x06, 0xdf, 0x97, 0xb5, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x33, 0x00, 0x0e, 0x0e, 0x0e, 0x0e, 0x03, 0x0d, 0x0e, 0x34, 0x0e, 0x02, 0x01, 0x16, 0x16, 0x16, +0xff, 0xff, 0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xf4, 0xaf, 0x76, 0xa4, 0x77, 0xa5, 0x04, 0xaf, 0x08, 0xff, 0x2e, 0xf0, 0x09, 0xfc, 0xfb, 0xab, 0xed, 0xae, 0xdf, 0xad, 0x0a, 0xf0, 0x23, 0x03, 0x03, 0x03, 0x03, 0x16, 0x04, 0x04, 0x1c, 0x02, 0x3a, 0x02, 0x0e, 0x0e, 0x0e, 0x3a, +0x0a, 0xfb, 0x0b, 0xfc, 0x6f, 0xaf, 0xfe, 0x1f, 0x88, 0xfd, 0x67, 0xaf, 0x77, 0xfd, 0x63, 0xaf, 0xfe, 0x1f, 0x80, 0xfd, 0x62, 0xaf, 0x0f, 0x1f, 0x80, 0xfd, 0x60, 0xaf, 0x77, 0xfd, 0x63, 0xaf, 0x02, 0x02, 0x04, 0x0e, 0x32, 0x04, 0x32, 0x04, 0x0e, 0x32, 0x04, 0x0e, 0x36, 0x04, 0x32, 0x04, +0xfe, 0x1f, 0x72, 0xfd, 0x62, 0xaf, 0x0f, 0x1f, 0x72, 0xfd, 0x52, 0xaf, 0xfe, 0x1f, 0x72, 0xfd, 0x0b, 0xa0, 0x0a, 0xa1, 0xf3, 0xaf, 0x06, 0xcf, 0x11, 0xfd, 0x08, 0xaf, 0xfe, 0x1f, 0x67, 0xfd, 0x0e, 0x32, 0x04, 0x0e, 0x32, 0x04, 0x0e, 0x32, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x1e, 0x0e, 0x34, +0x0b, 0xa0, 0x0a, 0xa1, 0xcf, 0xaf, 0x06, 0xcf, 0x11, 0xfd, 0xfe, 0xa8, 0xc9, 0xaf, 0x40, 0xfd, 0x08, 0xaf, 0x07, 0xff, 0x4e, 0xaf, 0xfa, 0xce, 0x5d, 0x5f, 0xf9, 0xaf, 0x00, 0xff, 0x6c, 0x1f, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x0e, 0x0c, 0x33, 0x1e, 0x02, 0x0c, 0x0e, 0x0d, 0x0e, 0x02, 0x0d, +0x7b, 0x5f, 0x12, 0xf1, 0xff, 0xa8, 0xff, 0xa9, 0xfb, 0xad, 0x5e, 0xae, 0x6c, 0x1f, 0x7b, 0x5f, 0xb6, 0xbc, 0xb7, 0xbb, 0xb3, 0xf8, 0xff, 0xac, 0x73, 0xaf, 0xff, 0x1f, 0x40, 0xfd, 0xb4, 0xbe, 0x0d, 0x3a, 0x0e, 0x0e, 0x0e, 0x0e, 0x0d, 0x0d, 0x01, 0x01, 0x00, 0x0e, 0x04, 0x0e, 0x34, 0x01, +0xb5, 0xbd, 0xb8, 0xfd, 0xf8, 0xce, 0xdd, 0x5f, 0xb8, 0xab, 0xfd, 0x2b, 0xff, 0x1b, 0x4b, 0xfd, 0xb8, 0xab, 0xfb, 0x2b, 0xff, 0x1b, 0x6a, 0xfd, 0xcc, 0x1f, 0x73, 0x1c, 0x50, 0xfd, 0xfe, 0x18, 0x01, 0x00, 0x0e, 0x0d, 0x04, 0x0e, 0x0e, 0x32, 0x04, 0x0e, 0x0e, 0x32, 0x0d, 0x04, 0x35, 0x0e, +0x15, 0xfd, 0x9e, 0xaf, 0xff, 0xad, 0x73, 0xac, 0xff, 0xab, 0xcc, 0xbf, 0xbb, 0xff, 0xbf, 0x1d, 0x34, 0xfd, 0xcf, 0x1e, 0x27, 0xfd, 0x9b, 0xaf, 0xf8, 0xeb, 0xfc, 0xaf, 0x5e, 0xcc, 0xfb, 0xdb, 0x32, 0x0c, 0x0e, 0x04, 0x0e, 0x0d, 0x0d, 0x0c, 0x32, 0x0c, 0x36, 0x0c, 0x0e, 0x0c, 0x0e, 0x0e, +0xf8, 0xad, 0x73, 0xed, 0xfe, 0xaf, 0x65, 0xce, 0xfb, 0xdd, 0xf8, 0xaf, 0x00, 0xff, 0x12, 0xf1, 0xf8, 0xa1, 0x73, 0xe1, 0xf0, 0xaf, 0x65, 0xc0, 0xfb, 0xd1, 0xff, 0xab, 0xff, 0xaf, 0x01, 0x4f, 0x0e, 0x04, 0x0c, 0x0e, 0x0e, 0x0e, 0x02, 0x3a, 0x0e, 0x04, 0x0c, 0x0e, 0x0e, 0x0e, 0x0e, 0x03, +0xbb, 0x1f, 0xf9, 0x1b, 0x21, 0xfd, 0x73, 0xbf, 0x73, 0xbf, 0x0b, 0xa0, 0x0a, 0xa1, 0xff, 0xaf, 0x06, 0xcf, 0x11, 0xfd, 0x0b, 0xa0, 0x0a, 0xa1, 0xed, 0xaf, 0x06, 0xcf, 0x09, 0xaf, 0x97, 0xbf, 0x0d, 0x0e, 0x34, 0x05, 0x01, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x1e, 0x1e, 0x0e, 0x02, 0x1e, 0x01, +0x0c, 0xaf, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa4, 0xff, 0xff, 0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xfe, 0xaf, 0x76, 0xa0, 0x77, 0xa1, 0x04, 0xa5, 0x2e, 0xf0, 0xc4, 0xaf, 0x16, 0x16, 0x16, 0x16, 0x16, 0x23, 0x03, 0x03, 0x03, 0x03, 0x16, 0x04, 0x04, 0x18, 0x3a, 0x0c, +0xfb, 0xab, 0xf5, 0xae, 0xdf, 0xad, 0x0a, 0xf0, 0x00, 0xfb, 0x01, 0xfc, 0xfe, 0x15, 0xf2, 0xfc, 0xc0, 0xaf, 0xb1, 0xaf, 0xcf, 0xaf, 0x06, 0xcf, 0x9e, 0xfc, 0xff, 0x15, 0xee, 0xfc, 0x6f, 0xaf, 0x0e, 0x0e, 0x0e, 0x3a, 0x02, 0x02, 0x0e, 0x34, 0x0c, 0x0c, 0x0e, 0x02, 0x33, 0x0e, 0x32, 0x04, +0xdc, 0xfc, 0xfe, 0x15, 0xe9, 0xfc, 0x6f, 0xaf, 0xfe, 0x1f, 0xdc, 0xfc, 0x63, 0xaf, 0xfe, 0x1f, 0xdc, 0xfc, 0x54, 0xaf, 0xdc, 0xfc, 0x04, 0xaf, 0xdc, 0xfc, 0x6f, 0xaf, 0xd7, 0xfc, 0xf3, 0xab, 0x36, 0x0e, 0x32, 0x04, 0x0e, 0x36, 0x04, 0x0e, 0x36, 0x04, 0x32, 0x04, 0x32, 0x04, 0x32, 0x04, +0xbf, 0x2b, 0xff, 0x1b, 0xd7, 0xfc, 0x01, 0xa0, 0x00, 0xa1, 0xf3, 0xaf, 0x06, 0xcf, 0x9e, 0xfc, 0xfb, 0xa1, 0x15, 0xa0, 0x00, 0xaf, 0x04, 0xcf, 0x01, 0xaf, 0x05, 0xcf, 0xfe, 0x15, 0xb9, 0xfc, 0x0e, 0x0e, 0x36, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x0e, 0x0e, 0x18, 0x02, 0x18, 0x02, 0x0e, 0x32, +0x72, 0xfe, 0x98, 0xac, 0x72, 0xab, 0xbf, 0x1c, 0xce, 0xfc, 0x6f, 0xfe, 0xfb, 0xa1, 0x1e, 0xa0, 0xfe, 0xaf, 0x01, 0xcf, 0xff, 0xaf, 0x04, 0xcf, 0xd5, 0x59, 0xd6, 0xf1, 0xd7, 0xff, 0xd9, 0xfa, 0x00, 0x04, 0x04, 0x0c, 0x35, 0x00, 0x0e, 0x0e, 0x0e, 0x02, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, +0xfb, 0xa1, 0x15, 0xa0, 0xff, 0xaf, 0x4d, 0xcf, 0x4e, 0xcf, 0xa2, 0xfc, 0x72, 0xff, 0x6f, 0xff, 0xd9, 0xff, 0xc0, 0xff, 0xd5, 0x17, 0xd6, 0xfc, 0xd7, 0xff, 0xd9, 0xfa, 0x71, 0xa5, 0x71, 0xff, 0x0e, 0x0e, 0x0e, 0x02, 0x02, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, +0x75, 0xab, 0xfe, 0x1b, 0xaa, 0xfc, 0xff, 0xdf, 0xaf, 0xfc, 0xfe, 0xab, 0x16, 0xc6, 0x05, 0xab, 0xa4, 0xfc, 0xff, 0xdf, 0xa8, 0xfc, 0xd9, 0xff, 0x71, 0xb5, 0x01, 0xa0, 0x00, 0xa1, 0xff, 0xaf, 0x04, 0x0e, 0x32, 0x0b, 0x33, 0x0e, 0x3a, 0x04, 0x36, 0x0b, 0x33, 0x00, 0x01, 0x1e, 0x1e, 0x0e, +0x06, 0xcf, 0x97, 0xb4, 0x02, 0xaf, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa4, 0xff, 0xff, 0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xfd, 0xaf, 0x76, 0xa0, 0x77, 0xa1, 0x04, 0xa5, 0x02, 0x01, 0x16, 0x16, 0x16, 0x16, 0x16, 0x23, 0x03, 0x03, 0x03, 0x03, 0x16, 0x04, 0x04, 0x18, +0x05, 0xa4, 0x2e, 0xf0, 0x00, 0xfc, 0xfb, 0xab, 0xf3, 0xae, 0xdf, 0xad, 0x0a, 0xf0, 0x01, 0xfb, 0x02, 0xfc, 0xfe, 0x15, 0x82, 0xfc, 0xfe, 0x14, 0x7d, 0xfc, 0x02, 0xa0, 0x01, 0xa1, 0xcf, 0xaf, 0x18, 0x3a, 0x02, 0x0e, 0x0e, 0x0e, 0x3a, 0x02, 0x02, 0x0e, 0x30, 0x0e, 0x34, 0x1e, 0x1e, 0x0e, +0x06, 0xcf, 0x17, 0xfc, 0xff, 0x15, 0x79, 0xfc, 0x63, 0xaf, 0x67, 0xfc, 0xfe, 0x15, 0x74, 0xfc, 0x63, 0xaf, 0xfe, 0x1f, 0x67, 0xfc, 0x6f, 0xaf, 0xfe, 0x1f, 0x67, 0xfc, 0x54, 0xaf, 0x67, 0xfc, 0x02, 0x33, 0x0e, 0x32, 0x04, 0x36, 0x0e, 0x32, 0x04, 0x0e, 0x36, 0x04, 0x0e, 0x36, 0x04, 0x32, +0x04, 0xaf, 0x67, 0xfc, 0x63, 0xaf, 0x62, 0xfc, 0xf3, 0xab, 0xbf, 0x2b, 0xff, 0x1b, 0x62, 0xfc, 0x02, 0xa0, 0x01, 0xa1, 0xf3, 0xaf, 0x06, 0xcf, 0x17, 0xfc, 0xfe, 0x15, 0x2e, 0xfc, 0xfa, 0xa3, 0x04, 0x32, 0x04, 0x32, 0x04, 0x0e, 0x0e, 0x36, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x0e, 0x32, 0x0e, +0xc6, 0xa2, 0x00, 0xaf, 0x62, 0xbf, 0x63, 0xfe, 0x5f, 0xb4, 0xfb, 0xa1, 0x1e, 0xa0, 0xfe, 0xaf, 0x01, 0xcf, 0xff, 0xaf, 0x04, 0xcf, 0x02, 0xac, 0x01, 0xab, 0x8e, 0xae, 0xfd, 0xad, 0xf5, 0xc4, 0x0e, 0x1a, 0x01, 0x00, 0x01, 0x0e, 0x0e, 0x0e, 0x02, 0x0e, 0x02, 0x1a, 0x1a, 0x0e, 0x0e, 0x3a, +0xd5, 0xbe, 0xd6, 0xbd, 0xd7, 0xbc, 0x04, 0xac, 0x03, 0xab, 0x8e, 0xae, 0xfd, 0xad, 0xf5, 0xc4, 0x04, 0xa0, 0x03, 0xa1, 0x01, 0x11, 0x3d, 0xfc, 0x02, 0x10, 0x3d, 0xfc, 0x63, 0xce, 0xdd, 0xff, 0x01, 0x01, 0x01, 0x1a, 0x1a, 0x0e, 0x0e, 0x3a, 0x1a, 0x1a, 0x1a, 0x32, 0x1a, 0x32, 0x0e, 0x0d, +0xcc, 0xff, 0xbb, 0xff, 0xcf, 0xbe, 0xd0, 0xbd, 0xd1, 0xbc, 0xd9, 0xf2, 0x5e, 0xd8, 0x5b, 0xff, 0x5a, 0xfe, 0x5d, 0xff, 0x5c, 0xff, 0x59, 0xff, 0x57, 0xff, 0x56, 0xff, 0xff, 0xab, 0x76, 0xdd, 0x0d, 0x0d, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x3a, +0x1b, 0xfc, 0x63, 0xff, 0xd9, 0xff, 0xc0, 0xff, 0xd5, 0x17, 0xd6, 0xfc, 0xd7, 0xff, 0xd9, 0xfa, 0x71, 0xa5, 0x71, 0xff, 0xfe, 0xab, 0x76, 0xdd, 0xfe, 0xab, 0x16, 0xc6, 0x05, 0xab, 0x1d, 0xfc, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0e, 0x3a, 0x0e, 0x3a, 0x04, 0x36, +0xff, 0xdf, 0x21, 0xfc, 0xd9, 0xff, 0x71, 0xb5, 0x02, 0xa0, 0x01, 0xa1, 0xff, 0xaf, 0x06, 0xcf, 0x00, 0xaf, 0x97, 0xbf, 0x03, 0xaf, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa4, 0xff, 0xff, 0x0b, 0x33, 0x00, 0x01, 0x1e, 0x1e, 0x0e, 0x02, 0x1e, 0x01, 0x16, 0x16, 0x16, 0x16, 0x16, 0x23, +0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xe1, 0xaf, 0xff, 0xaf, 0x17, 0xff, 0x18, 0xff, 0x19, 0xff, 0x1a, 0xff, 0xff, 0xaf, 0x1b, 0xff, 0x1c, 0xff, 0x1d, 0xff, 0x1e, 0xff, 0x76, 0xa4, 0x03, 0x03, 0x03, 0x03, 0x16, 0x0e, 0x02, 0x02, 0x02, 0x02, 0x0e, 0x02, 0x02, 0x02, 0x02, 0x04, +0x77, 0xa5, 0x05, 0xaf, 0x01, 0xff, 0x04, 0xaf, 0x02, 0xff, 0x07, 0xaf, 0x03, 0xff, 0x06, 0xaf, 0x04, 0xff, 0x08, 0xaf, 0x11, 0xff, 0x09, 0xaf, 0x12, 0xff, 0x10, 0xaf, 0x13, 0xff, 0x12, 0xaf, 0x04, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, +0x05, 0xff, 0x11, 0xaf, 0x06, 0xff, 0x14, 0xaf, 0x07, 0xff, 0x13, 0xaf, 0x08, 0xff, 0x16, 0xaf, 0x09, 0xff, 0x15, 0xaf, 0x0a, 0xff, 0x18, 0xaf, 0x0b, 0xff, 0x17, 0xaf, 0x0c, 0xff, 0x1a, 0xaf, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, +0x0d, 0xff, 0x19, 0xaf, 0x0e, 0xff, 0x1c, 0xaf, 0x0f, 0xff, 0x1b, 0xaf, 0x10, 0xff, 0x2e, 0xf0, 0x14, 0xfc, 0xfb, 0xab, 0xf2, 0xae, 0xdf, 0xad, 0xef, 0xef, 0x15, 0xfb, 0x16, 0xfc, 0x63, 0xaf, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x02, 0x3a, 0x02, 0x0e, 0x0e, 0x0e, 0x3a, 0x02, 0x02, 0x04, +0xfe, 0x1f, 0xbf, 0xfb, 0x6f, 0xaf, 0xfe, 0x1f, 0xbf, 0xfb, 0x04, 0xaf, 0xbf, 0xfb, 0x54, 0xaf, 0xfd, 0x1f, 0xbf, 0xfb, 0x54, 0xaf, 0xba, 0xfb, 0xf3, 0xab, 0xbf, 0x2b, 0xff, 0x1b, 0xba, 0xfb, 0x0e, 0x36, 0x04, 0x0e, 0x36, 0x04, 0x32, 0x04, 0x0e, 0x36, 0x04, 0x32, 0x04, 0x0e, 0x0e, 0x36, +0x16, 0xa0, 0x15, 0xa1, 0xf3, 0xaf, 0x03, 0xcf, 0x15, 0xfa, 0x54, 0xaf, 0xb3, 0xfb, 0x16, 0xa0, 0x15, 0xa1, 0xf6, 0xaf, 0x03, 0xcf, 0x15, 0xfa, 0x02, 0xac, 0x03, 0xcc, 0x01, 0xfb, 0xc0, 0x1b, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x04, 0x36, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x1e, 0x0e, 0x1f, 0x0e, +0xad, 0xfb, 0x03, 0x1c, 0x75, 0xfb, 0x04, 0xac, 0x03, 0xab, 0xff, 0x1b, 0xa7, 0xfb, 0xfc, 0x1c, 0x75, 0xfb, 0xbf, 0x1b, 0xa3, 0xfb, 0xff, 0x1c, 0x75, 0xfb, 0x11, 0xaf, 0xfe, 0x1f, 0x75, 0xfb, 0x32, 0x0e, 0x30, 0x1e, 0x1e, 0x0e, 0x32, 0x0e, 0x34, 0x0e, 0x32, 0x0e, 0x30, 0x1e, 0x0e, 0x30, +0x12, 0xaf, 0xfe, 0x1f, 0x75, 0xfb, 0x13, 0xaf, 0xfe, 0x1f, 0x75, 0xfb, 0x06, 0xa0, 0x05, 0xa1, 0xff, 0x11, 0x94, 0xfb, 0xfa, 0x10, 0x75, 0xfb, 0xf3, 0x11, 0x90, 0xfb, 0x7f, 0x10, 0x75, 0xfb, 0x1e, 0x0e, 0x30, 0x1e, 0x0e, 0x30, 0x1e, 0x1e, 0x0e, 0x32, 0x0e, 0x34, 0x0e, 0x32, 0x0e, 0x30, +0x08, 0xac, 0x07, 0xab, 0xff, 0x1b, 0x8a, 0xfb, 0xfa, 0x1c, 0x75, 0xfb, 0xf3, 0x1b, 0x86, 0xfb, 0x7f, 0x1c, 0x75, 0xfb, 0x0a, 0xa0, 0x09, 0xa1, 0xfe, 0x11, 0x80, 0xfb, 0x0c, 0x10, 0x75, 0xfb, 0x1e, 0x1e, 0x0e, 0x32, 0x0e, 0x34, 0x0e, 0x32, 0x0e, 0x30, 0x1e, 0x1e, 0x0e, 0x32, 0x0e, 0x30, +0x0c, 0xac, 0x0b, 0xab, 0xff, 0x1b, 0x7a, 0xfb, 0xf6, 0x1c, 0x75, 0xfb, 0xf3, 0x1b, 0x76, 0xfb, 0x7f, 0x1c, 0x70, 0xfb, 0x16, 0xa0, 0x15, 0xa1, 0xcf, 0xaf, 0x03, 0xcf, 0x15, 0xfa, 0x04, 0xac, 0x1e, 0x1e, 0x0e, 0x32, 0x0e, 0x34, 0x0e, 0x32, 0x0e, 0x34, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x1e, +0x03, 0xab, 0x01, 0x1b, 0x6b, 0xfb, 0x02, 0x1c, 0x4c, 0xfb, 0x06, 0xa0, 0x05, 0xa1, 0x07, 0x11, 0x65, 0xfb, 0x08, 0x10, 0x4c, 0xfb, 0x0e, 0xac, 0x0d, 0xab, 0x0f, 0x1b, 0x5f, 0xfb, 0x10, 0x1c, 0x1e, 0x1e, 0x32, 0x1e, 0x30, 0x1e, 0x1e, 0x1e, 0x32, 0x1e, 0x30, 0x1e, 0x1e, 0x1e, 0x32, 0x1e, +0x4c, 0xfb, 0x0a, 0x1e, 0x09, 0x5d, 0x08, 0xac, 0x07, 0xab, 0x32, 0xc5, 0xe0, 0xaf, 0xd1, 0xaf, 0x0c, 0xae, 0x0b, 0xad, 0xf7, 0xee, 0xff, 0x7f, 0xf7, 0xed, 0xed, 0xbf, 0x01, 0xae, 0xdf, 0x11, 0x30, 0x1f, 0x1f, 0x1e, 0x1e, 0x3a, 0x0c, 0x0c, 0x1e, 0x1e, 0x0e, 0x03, 0x0e, 0x0c, 0x16, 0x0c, +0x4d, 0xfb, 0xef, 0x10, 0x47, 0xfb, 0x16, 0xa0, 0x15, 0xa1, 0xed, 0xaf, 0x03, 0xcf, 0x15, 0xfa, 0x72, 0xfe, 0x98, 0xac, 0x72, 0xab, 0xbf, 0x1c, 0x46, 0xfb, 0x54, 0xfe, 0x53, 0xff, 0x11, 0xaf, 0x32, 0x0c, 0x34, 0x1e, 0x1e, 0x0e, 0x02, 0x33, 0x00, 0x04, 0x04, 0x0c, 0x35, 0x00, 0x00, 0x1e, +0x52, 0xbf, 0xfa, 0xa1, 0x97, 0xa0, 0x01, 0xaf, 0x00, 0xcf, 0x02, 0xaf, 0x01, 0xcf, 0x03, 0xaf, 0x02, 0xcf, 0x04, 0xaf, 0x03, 0xcf, 0x0d, 0xaf, 0x0c, 0xcf, 0x0e, 0xaf, 0x0d, 0xcf, 0x0f, 0xaf, 0x01, 0x0e, 0x0e, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, +0x0e, 0xcf, 0x10, 0xaf, 0x0f, 0xcf, 0x05, 0xaf, 0x10, 0xcf, 0x06, 0xaf, 0x11, 0xcf, 0x07, 0xaf, 0x12, 0xcf, 0x08, 0xaf, 0x13, 0xcf, 0xf9, 0xa1, 0xfa, 0xa0, 0x24, 0xaf, 0x4f, 0xbf, 0x25, 0xaf, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x0e, 0x0e, 0x18, 0x01, 0x18, +0x4e, 0xbf, 0x12, 0xaf, 0x51, 0xbf, 0x4e, 0xaf, 0xf5, 0xce, 0x5d, 0x5f, 0xf9, 0xaf, 0x00, 0xff, 0xfa, 0xab, 0x93, 0xac, 0x12, 0xf1, 0x13, 0xaf, 0x50, 0xbf, 0x05, 0xaf, 0x4d, 0xbf, 0x06, 0xaf, 0x01, 0x1e, 0x01, 0x0c, 0x0e, 0x0d, 0x0e, 0x02, 0x0e, 0x0e, 0x3a, 0x1e, 0x01, 0x1e, 0x01, 0x1e, +0x4c, 0xbf, 0x09, 0xaf, 0x4b, 0xbf, 0x0a, 0xaf, 0x4a, 0xbf, 0x0b, 0xaf, 0x49, 0xbf, 0x0c, 0xaf, 0x48, 0xbf, 0xf9, 0xa1, 0xfa, 0xa0, 0x10, 0xaf, 0xff, 0xfa, 0x10, 0xaf, 0x47, 0xbf, 0xf7, 0xfa, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x0e, 0x0e, 0x18, 0x36, 0x18, 0x01, 0x33, +0xb9, 0xab, 0xf3, 0xeb, 0xfc, 0xaf, 0xbc, 0xaf, 0xff, 0xab, 0xfa, 0xcc, 0x47, 0xbc, 0xc2, 0xef, 0xf9, 0xa3, 0xfa, 0xa2, 0x11, 0xaf, 0xfe, 0x1f, 0xe7, 0xfa, 0xfa, 0xa1, 0x97, 0xa0, 0x12, 0xaf, 0x04, 0x0e, 0x0c, 0x0c, 0x0e, 0x0e, 0x01, 0x3a, 0x0e, 0x0e, 0x1a, 0x0e, 0x32, 0x0e, 0x0e, 0x1a, +0x19, 0xcf, 0x13, 0xaf, 0x1a, 0xcf, 0x14, 0xaf, 0x1b, 0xcf, 0x15, 0xaf, 0x1c, 0xcf, 0xaa, 0xfa, 0x09, 0xad, 0xa7, 0xae, 0xb9, 0xab, 0xe0, 0x2b, 0xbc, 0xaf, 0xff, 0xab, 0xc0, 0xce, 0xb1, 0xdd, 0x02, 0x1a, 0x02, 0x1a, 0x02, 0x1a, 0x02, 0x33, 0x0e, 0x0e, 0x04, 0x0e, 0x0c, 0x0e, 0x0c, 0x0c, +0x00, 0xaf, 0x17, 0xff, 0xba, 0xab, 0xe0, 0x2b, 0xbc, 0xaf, 0xff, 0xab, 0xc0, 0xce, 0xb1, 0xdd, 0x00, 0xaf, 0x18, 0xff, 0xbb, 0xab, 0xe0, 0x2b, 0xbc, 0xaf, 0xff, 0xab, 0xc0, 0xce, 0xb1, 0xdd, 0x18, 0x02, 0x04, 0x0e, 0x0c, 0x0e, 0x0c, 0x0c, 0x18, 0x02, 0x04, 0x0e, 0x0c, 0x0e, 0x0c, 0x0c, +0x00, 0xaf, 0x19, 0xff, 0xbb, 0xac, 0xe0, 0x2c, 0xbc, 0xab, 0xe0, 0x2b, 0xbf, 0x1c, 0xc0, 0xfa, 0xbc, 0xab, 0xe0, 0x2b, 0xbc, 0xaf, 0xff, 0xab, 0xc0, 0xce, 0xb1, 0xdd, 0xb7, 0xfa, 0xbc, 0xab, 0x18, 0x02, 0x04, 0x0e, 0x04, 0x0e, 0x0c, 0x36, 0x04, 0x0e, 0x0c, 0x0e, 0x0c, 0x0c, 0x33, 0x04, +0xaa, 0x8b, 0xe0, 0x2b, 0xbc, 0xaf, 0xff, 0xab, 0xc0, 0xaf, 0xa7, 0xc0, 0xb1, 0xaf, 0x09, 0xd1, 0x00, 0xaf, 0x1a, 0xff, 0xfa, 0xa1, 0x97, 0xa0, 0x17, 0xaf, 0x19, 0xcf, 0x18, 0xaf, 0x1a, 0xcf, 0x0e, 0x0e, 0x0c, 0x0e, 0x0c, 0x0e, 0x0c, 0x0e, 0x18, 0x02, 0x0e, 0x0e, 0x1e, 0x02, 0x1e, 0x02, +0x19, 0xaf, 0x1b, 0xcf, 0x1a, 0xaf, 0x1c, 0xcf, 0xc2, 0xef, 0xf9, 0xa3, 0xfa, 0xa2, 0x19, 0xaf, 0x1a, 0xbf, 0x1b, 0xbf, 0x1c, 0xbf, 0x98, 0xfa, 0xfa, 0xa1, 0x97, 0xa0, 0x19, 0xaf, 0x1d, 0xcf, 0x1e, 0x02, 0x1e, 0x02, 0x3a, 0x0e, 0x0e, 0x1a, 0x1a, 0x1a, 0x1a, 0x36, 0x0e, 0x0e, 0x1a, 0x02, +0x1a, 0xaf, 0x1e, 0xcf, 0x1b, 0xaf, 0x1f, 0xcf, 0x1c, 0xaf, 0x20, 0xcf, 0x85, 0xfa, 0xba, 0xaf, 0x1e, 0xff, 0xbb, 0xaf, 0x1d, 0xff, 0xbc, 0xaf, 0x1c, 0xff, 0xff, 0xaf, 0x1b, 0xff, 0xfa, 0xa1, 0x1a, 0x02, 0x1a, 0x02, 0x1a, 0x02, 0x33, 0x04, 0x02, 0x04, 0x02, 0x04, 0x02, 0x0e, 0x02, 0x0e, +0x97, 0xa0, 0x1b, 0xaf, 0x1d, 0xcf, 0x1c, 0xaf, 0x1e, 0xcf, 0x1d, 0xaf, 0x1f, 0xcf, 0x1e, 0xaf, 0x20, 0xcf, 0xc2, 0xef, 0xf9, 0xa1, 0xfa, 0xa0, 0x1e, 0xac, 0x1d, 0xab, 0x00, 0x1b, 0x7d, 0xfa, 0x0e, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x3a, 0x0e, 0x0e, 0x18, 0x18, 0x0e, 0x32, +0x00, 0x1c, 0x7a, 0xfa, 0x46, 0xbb, 0x45, 0xbc, 0x76, 0xfa, 0x05, 0xaf, 0x46, 0xbf, 0x06, 0xaf, 0x45, 0xbf, 0xf9, 0xa1, 0xfa, 0xa0, 0x1f, 0xaf, 0x44, 0xbf, 0x71, 0xab, 0xfe, 0x1b, 0x6c, 0xfa, 0x0e, 0x36, 0x01, 0x01, 0x33, 0x1e, 0x01, 0x1e, 0x01, 0x0e, 0x0e, 0x18, 0x01, 0x04, 0x0e, 0x36, +0x21, 0xaf, 0xfe, 0x1f, 0x69, 0xfa, 0x70, 0xa1, 0x10, 0xa0, 0x67, 0xfa, 0x70, 0xa1, 0x0f, 0xa0, 0x00, 0xaf, 0x43, 0xbf, 0x40, 0x00, 0x3f, 0x00, 0x3c, 0xff, 0x3a, 0xff, 0x3b, 0xff, 0x39, 0xff, 0x18, 0x0e, 0x32, 0x0e, 0x0e, 0x33, 0x0e, 0x0e, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x38, 0xff, 0x35, 0xff, 0x31, 0xff, 0x30, 0xff, 0x15, 0xff, 0x14, 0xff, 0x13, 0xff, 0x12, 0xff, 0x11, 0xff, 0x10, 0xff, 0x0f, 0xff, 0x0c, 0xff, 0x0e, 0xff, 0x0d, 0xff, 0x63, 0xfe, 0x62, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x50, 0xaf, 0x46, 0xfa, 0xfa, 0xa1, 0x97, 0xa0, 0xfb, 0xaf, 0x0a, 0xcf, 0x6a, 0xaf, 0x0b, 0xcf, 0x3d, 0xfa, 0x50, 0xaf, 0xfe, 0x1f, 0x3d, 0xfa, 0xfa, 0xa1, 0x97, 0xa0, 0xfb, 0xaf, 0x0a, 0xcf, 0x04, 0x32, 0x0e, 0x0e, 0x0e, 0x02, 0x0e, 0x02, 0x33, 0x04, 0x0e, 0x32, 0x0e, 0x0e, 0x0e, 0x02, +0x64, 0xaf, 0x0b, 0xcf, 0x02, 0xac, 0x01, 0xab, 0x8e, 0xae, 0xfd, 0xad, 0xf5, 0xc4, 0xd5, 0xbe, 0xd6, 0xbd, 0xd7, 0xbc, 0x04, 0xac, 0x03, 0xab, 0x8e, 0xae, 0xfd, 0xad, 0xf5, 0xc4, 0x04, 0xa0, 0x0e, 0x02, 0x1e, 0x1e, 0x0e, 0x0e, 0x3a, 0x01, 0x01, 0x01, 0x1e, 0x1e, 0x0e, 0x0e, 0x3a, 0x1e, +0x03, 0xa1, 0x01, 0x11, 0x26, 0xfa, 0x02, 0x10, 0x26, 0xfa, 0x63, 0xce, 0xdd, 0xff, 0xcc, 0xff, 0xbb, 0xff, 0xcf, 0xbe, 0xd0, 0xbd, 0xd1, 0xbc, 0xd9, 0xf2, 0x5e, 0xd8, 0xfb, 0xa1, 0x1e, 0xa0, 0x1e, 0x1e, 0x32, 0x1e, 0x32, 0x0e, 0x0d, 0x0d, 0x0d, 0x01, 0x01, 0x01, 0x00, 0x00, 0x0e, 0x0e, +0xfe, 0xaf, 0x01, 0xcf, 0xff, 0xaf, 0x04, 0xcf, 0xff, 0xab, 0x76, 0xdd, 0x16, 0xa0, 0x15, 0xa1, 0xff, 0xaf, 0x03, 0xcf, 0x14, 0xaf, 0x97, 0xbf, 0x1f, 0xaf, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x3a, 0x1e, 0x1e, 0x0e, 0x02, 0x1e, 0x01, 0x16, 0x16, 0x16, 0x16, +0x01, 0xa4, 0xff, 0xff, 0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xfa, 0xaf, 0x2e, 0xf0, 0x01, 0xfc, 0xfb, 0xab, 0xf1, 0xae, 0xdf, 0xad, 0x0a, 0xf0, 0xc4, 0xaf, 0xb5, 0xaf, 0xff, 0xaf, 0x16, 0x23, 0x03, 0x03, 0x03, 0x03, 0x16, 0x3a, 0x02, 0x0e, 0x0e, 0x0e, 0x3a, 0x0c, 0x0c, 0x0e, +0x02, 0xff, 0x63, 0xaf, 0xfe, 0x1f, 0xf8, 0xf9, 0x62, 0xaf, 0x0f, 0x1f, 0xf5, 0xf9, 0xf3, 0xaf, 0x06, 0xef, 0xd8, 0xf9, 0x72, 0xff, 0x63, 0xff, 0x54, 0xff, 0xfe, 0xaf, 0x02, 0xff, 0xd9, 0xff, 0x02, 0x04, 0x0e, 0x32, 0x04, 0x0e, 0x36, 0x0e, 0x02, 0x33, 0x00, 0x00, 0x00, 0x0e, 0x02, 0x00, +0xc0, 0xff, 0xd5, 0x17, 0xd6, 0xfc, 0xd7, 0xff, 0xd9, 0xfa, 0x71, 0xaf, 0x03, 0xff, 0x71, 0xff, 0xfe, 0xab, 0x76, 0xdd, 0x75, 0xab, 0xe5, 0xf9, 0xfe, 0xab, 0x16, 0xc6, 0x05, 0xab, 0xdd, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00, 0x0e, 0x3a, 0x04, 0x32, 0x0e, 0x3a, 0x04, 0x36, +0xff, 0xdf, 0xe1, 0xf9, 0xd9, 0xff, 0x03, 0xaf, 0x71, 0xbf, 0xff, 0xaf, 0x06, 0xef, 0x01, 0xaf, 0x97, 0xbf, 0x02, 0xaf, 0xfe, 0x1f, 0x9c, 0xf9, 0x78, 0xab, 0xdf, 0x2b, 0xff, 0x1b, 0x9c, 0xf9, 0x0b, 0x33, 0x00, 0x1e, 0x01, 0x0e, 0x02, 0x1e, 0x01, 0x1e, 0x0e, 0x32, 0x04, 0x0e, 0x0e, 0x36, +0xfb, 0xa1, 0x7a, 0xa0, 0x00, 0xab, 0xfe, 0x2b, 0xff, 0x1b, 0x9c, 0xf9, 0x2e, 0xf0, 0xc4, 0xaf, 0xec, 0xab, 0xc1, 0xad, 0xd4, 0xef, 0x04, 0xfb, 0x05, 0xfc, 0xc0, 0xaf, 0xb1, 0xaf, 0xfe, 0xaf, 0x0e, 0x0e, 0x18, 0x0e, 0x0e, 0x36, 0x3a, 0x0c, 0x0e, 0x0e, 0x3a, 0x02, 0x02, 0x0c, 0x0c, 0x0e, +0x03, 0xcf, 0xfd, 0xaf, 0x04, 0xcf, 0xff, 0xaf, 0x05, 0xcf, 0xff, 0xaf, 0x06, 0xcf, 0xff, 0xaf, 0x07, 0xcf, 0xff, 0xaf, 0x08, 0xcf, 0xf6, 0xcc, 0xbb, 0x5f, 0xf9, 0xaf, 0x00, 0xff, 0x6a, 0xae, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x0d, 0x0e, 0x02, 0x04, +0x6b, 0xad, 0x12, 0xf1, 0x05, 0xa0, 0x04, 0xa1, 0xff, 0xaf, 0x0f, 0xcf, 0xff, 0xaf, 0x10, 0xcf, 0xff, 0xaf, 0x11, 0xcf, 0xff, 0xaf, 0x12, 0xcf, 0xff, 0xaf, 0x13, 0xcf, 0xff, 0xaf, 0x14, 0xcf, 0x04, 0x3a, 0x1e, 0x1e, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, +0xff, 0xaf, 0x15, 0xcf, 0x97, 0xb4, 0x06, 0xaf, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa4, 0xff, 0xff, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xf2, 0xaf, 0x76, 0xa0, 0x77, 0xa1, 0x05, 0xaf, 0x0e, 0x02, 0x01, 0x16, 0x16, 0x16, 0x16, 0x16, 0x23, 0x03, 0x03, 0x03, 0x16, 0x04, 0x04, 0x18, +0x00, 0xff, 0x04, 0xaf, 0x01, 0xff, 0x07, 0xaf, 0x02, 0xff, 0x06, 0xaf, 0x03, 0xff, 0x09, 0xaf, 0x04, 0xff, 0x08, 0xaf, 0x05, 0xff, 0x0b, 0xaf, 0x06, 0xff, 0x0a, 0xaf, 0x07, 0xff, 0x0d, 0xaf, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, +0x08, 0xff, 0x0c, 0xaf, 0x09, 0xff, 0x0f, 0xaf, 0x0a, 0xff, 0x0e, 0xaf, 0x0b, 0xff, 0x11, 0xaf, 0x0c, 0xff, 0x10, 0xaf, 0x0d, 0xff, 0x2e, 0xf0, 0xc5, 0xaf, 0xfb, 0xab, 0xec, 0xae, 0xdf, 0xad, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x18, 0x02, 0x3a, 0x0c, 0x0e, 0x0e, 0x0e, +0xef, 0xef, 0xc2, 0xaf, 0xb3, 0xaf, 0x54, 0xaf, 0x64, 0xf9, 0x4e, 0xac, 0x4f, 0xab, 0x00, 0x1b, 0x64, 0xf9, 0x01, 0x1c, 0x61, 0xf9, 0xfd, 0xaf, 0x03, 0xdf, 0xdf, 0xf8, 0x54, 0xaf, 0xfe, 0x1f, 0x3a, 0x0c, 0x0c, 0x04, 0x36, 0x04, 0x04, 0x1e, 0x32, 0x1e, 0x36, 0x0e, 0x02, 0x33, 0x04, 0x0e, +0x5c, 0xf9, 0x12, 0xaf, 0x59, 0xf9, 0xf3, 0xaf, 0x03, 0xdf, 0xdf, 0xf8, 0x03, 0xac, 0x05, 0xcc, 0x02, 0xfb, 0xf3, 0x1b, 0x53, 0xf9, 0x85, 0x1c, 0x38, 0xf9, 0x05, 0xac, 0x04, 0xab, 0xff, 0x1b, 0x32, 0x04, 0x36, 0x0e, 0x02, 0x33, 0x1e, 0x0e, 0x1f, 0x0e, 0x32, 0x0e, 0x30, 0x1e, 0x1e, 0x0e, +0x4d, 0xf9, 0xfa, 0x1c, 0x38, 0xf9, 0xf3, 0x1b, 0x49, 0xf9, 0x7f, 0x1c, 0x38, 0xf9, 0x07, 0xac, 0x06, 0xab, 0xfe, 0x1b, 0x43, 0xf9, 0x0c, 0x1c, 0x38, 0xf9, 0x09, 0xac, 0x08, 0xab, 0xff, 0x1b, 0x32, 0x0e, 0x34, 0x0e, 0x32, 0x0e, 0x30, 0x1e, 0x1e, 0x0e, 0x32, 0x0e, 0x30, 0x1e, 0x1e, 0x0e, +0x3d, 0xf9, 0xf6, 0x1c, 0x38, 0xf9, 0xf3, 0x1b, 0x39, 0xf9, 0x7f, 0x1c, 0x35, 0xf9, 0xcf, 0xaf, 0x03, 0xdf, 0xdf, 0xf8, 0x03, 0xac, 0x02, 0xab, 0x04, 0x1b, 0x30, 0xf9, 0x05, 0x1c, 0x17, 0xf9, 0x32, 0x0e, 0x34, 0x0e, 0x32, 0x0e, 0x34, 0x0e, 0x02, 0x33, 0x1e, 0x1e, 0x1e, 0x32, 0x1e, 0x30, +0x0b, 0xac, 0x0a, 0xab, 0x0c, 0x1b, 0x2a, 0xf9, 0x0d, 0x1c, 0x17, 0xf9, 0x07, 0x1e, 0x06, 0x5d, 0x05, 0xac, 0x04, 0xab, 0x32, 0xc5, 0xe0, 0xaf, 0xd1, 0xaf, 0x09, 0xae, 0x08, 0xad, 0xf7, 0xee, 0x1e, 0x1e, 0x1e, 0x32, 0x1e, 0x30, 0x1f, 0x1f, 0x1e, 0x1e, 0x3a, 0x0c, 0x0c, 0x1e, 0x1e, 0x0e, +0xff, 0x7f, 0xf7, 0xed, 0xed, 0xbf, 0x01, 0xae, 0xdf, 0x11, 0x18, 0xf9, 0xef, 0x10, 0x14, 0xf9, 0xed, 0xaf, 0x03, 0xdf, 0xdf, 0xf8, 0x1b, 0xfe, 0xfa, 0xa1, 0x97, 0xa0, 0x0a, 0xaf, 0x3d, 0xcf, 0x03, 0x0e, 0x0c, 0x16, 0x0c, 0x32, 0x0c, 0x34, 0x0e, 0x02, 0x33, 0x00, 0x0e, 0x0e, 0x1e, 0x02, +0x0b, 0xaf, 0x3e, 0xcf, 0x0c, 0xaf, 0x3f, 0xcf, 0x0d, 0xaf, 0x40, 0xcf, 0x02, 0xaf, 0x41, 0xcf, 0x03, 0xaf, 0x42, 0xcf, 0x04, 0xaf, 0x43, 0xcf, 0x05, 0xaf, 0x44, 0xcf, 0xf9, 0xa1, 0xfa, 0xa0, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x1e, 0x02, 0x0e, 0x0e, +0x1e, 0xac, 0x1d, 0xab, 0x00, 0x1b, 0xf9, 0xf8, 0x00, 0x1c, 0xf6, 0xf8, 0x1e, 0xbb, 0x1d, 0xbc, 0xf2, 0xf8, 0x02, 0xaf, 0x1e, 0xbf, 0x03, 0xaf, 0x1d, 0xbf, 0xf9, 0xa1, 0xfa, 0xa0, 0x1f, 0xaf, 0x18, 0x18, 0x0e, 0x32, 0x0e, 0x36, 0x01, 0x01, 0x33, 0x1e, 0x01, 0x1e, 0x01, 0x0e, 0x0e, 0x18, +0x1c, 0xbf, 0x02, 0xaf, 0x24, 0xbf, 0x03, 0xaf, 0x23, 0xbf, 0x06, 0xaf, 0x22, 0xbf, 0x07, 0xaf, 0x21, 0xbf, 0x08, 0xaf, 0x20, 0xbf, 0x09, 0xaf, 0x1f, 0xbf, 0x12, 0xfe, 0xff, 0xaf, 0x03, 0xdf, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x1e, 0x01, 0x00, 0x0e, 0x02, +0x97, 0xb5, 0x0e, 0xaf, 0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0xff, 0xff, 0xff, 0xff, 0xf9, 0xa1, 0x87, 0xa0, 0xff, 0xaf, 0x00, 0xcf, 0xfb, 0xaf, 0x6b, 0xbf, 0x6a, 0xaf, 0x6a, 0xbf, 0xfa, 0xa1, 0x01, 0x16, 0x16, 0x16, 0x16, 0x23, 0x23, 0x0e, 0x0e, 0x0e, 0x02, 0x0e, 0x01, 0x0e, 0x01, 0x0e, +0xc6, 0xa0, 0xfb, 0xaf, 0x05, 0xcf, 0x6a, 0xaf, 0x06, 0xcf, 0x25, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x74, 0xff, 0x75, 0xff, 0x78, 0xff, 0x79, 0xfe, 0xa1, 0xed, 0xa0, 0xe5, 0xaf, 0x00, 0xcf, 0x0e, 0x0e, 0x02, 0x0e, 0x02, 0x00, 0x23, 0x23, 0x03, 0x03, 0x03, 0x03, 0x0e, 0x0e, 0x0e, 0x02, +0xfe, 0xa1, 0xeb, 0xa0, 0x68, 0xaf, 0x00, 0xcf, 0xfe, 0xa1, 0x55, 0xa0, 0x8a, 0xaf, 0x00, 0xcf, 0xfe, 0xa9, 0x34, 0xa8, 0x80, 0xaf, 0x91, 0xaf, 0x00, 0xab, 0xfd, 0xbb, 0x00, 0xcb, 0xfe, 0xa1, 0x0e, 0x0e, 0x0e, 0x02, 0x0e, 0x0e, 0x0e, 0x02, 0x0e, 0x0e, 0x0c, 0x0c, 0x18, 0x0e, 0x02, 0x0e, +0x61, 0xa0, 0xf3, 0xaf, 0x00, 0xcf, 0xfe, 0xab, 0x5f, 0xac, 0xc2, 0xaf, 0xb3, 0xaf, 0xcc, 0xaf, 0x00, 0xdf, 0xfe, 0xad, 0x60, 0xae, 0xe4, 0xaf, 0xd5, 0xaf, 0xcc, 0xaf, 0x00, 0xef, 0xfe, 0xa3, 0x0e, 0x0e, 0x02, 0x0e, 0x0e, 0x0c, 0x0c, 0x0e, 0x02, 0x0e, 0x0e, 0x0c, 0x0c, 0x0e, 0x02, 0x0e, +0x62, 0xa2, 0xfd, 0xaf, 0x00, 0xdf, 0xf2, 0xaf, 0x00, 0xcf, 0xc4, 0xaf, 0xb5, 0xaf, 0xdd, 0xaf, 0x00, 0xef, 0xe4, 0xaf, 0xd5, 0xaf, 0xfe, 0xaf, 0x00, 0xef, 0xfd, 0xaf, 0x00, 0xdf, 0xf1, 0xaf, 0x0e, 0x0e, 0x02, 0x0e, 0x02, 0x0c, 0x0c, 0x0e, 0x02, 0x0c, 0x0c, 0x0e, 0x02, 0x0e, 0x02, 0x0e, +0x00, 0xcf, 0xc4, 0xaf, 0xb5, 0xaf, 0x8f, 0xaf, 0x00, 0xef, 0xe4, 0xaf, 0xd5, 0xaf, 0x99, 0xaf, 0x00, 0xef, 0xfd, 0xaf, 0x00, 0xdf, 0xf0, 0xaf, 0x00, 0xcf, 0xc4, 0xaf, 0xb5, 0xaf, 0xba, 0xaf, 0x02, 0x0c, 0x0c, 0x0e, 0x02, 0x0c, 0x0c, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0c, 0x0c, 0x0e, +0x00, 0xef, 0xe4, 0xaf, 0xd5, 0xaf, 0xbb, 0xaf, 0x00, 0xef, 0xfd, 0xaf, 0x00, 0xdf, 0xff, 0xaf, 0x00, 0xcf, 0xfe, 0xaf, 0x00, 0xdf, 0xfe, 0xa1, 0x5d, 0xa0, 0xc4, 0xaf, 0xb5, 0xaf, 0x00, 0xaf, 0x02, 0x0c, 0x0c, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x02, 0x0e, 0x0e, 0x0c, 0x0c, 0x18, +0x00, 0xef, 0xfe, 0xa1, 0x5e, 0xa0, 0x00, 0xab, 0x78, 0x2b, 0xcf, 0xbb, 0xe0, 0xaf, 0xd1, 0xaf, 0x00, 0xcb, 0xfd, 0xaf, 0x00, 0xdf, 0x82, 0xaf, 0x93, 0xaf, 0x00, 0xab, 0x02, 0x2b, 0x00, 0xdb, 0x02, 0x0e, 0x0e, 0x18, 0x0e, 0x0e, 0x0c, 0x0c, 0x02, 0x0e, 0x02, 0x0c, 0x0c, 0x1a, 0x0e, 0x02, +0x01, 0xa9, 0x01, 0xa8, 0x01, 0xa5, 0x01, 0xa4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x16, 0x16, 0x16, 0x16, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x3f, 0x3f, 0x3f, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, +0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0a, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x00, 0x00 +}; + +const uint32_t EMPatchArray_size = sizeof(EMPatchArray); diff --git a/chipset/em9301/btstack_chipset_em9301.c b/chipset/em9301/btstack_chipset_em9301.c index d956fee826..f3ff5cfe2f 100644 --- a/chipset/em9301/btstack_chipset_em9301.c +++ b/chipset/em9301/btstack_chipset_em9301.c @@ -53,26 +53,40 @@ #include /* memcpy */ #include "hci.h" -// should go to some common place -#define OPCODE(ogf, ocf) (ocf | ogf << 10) +// general vendor opcodes +#define HCI_OPCODE_EM_SET_PUBLIC_ADDRESS 0x02 +#define HCI_OPCODE_EM_SET_UART_BAUD_RATE 0x07 +#define HCI_OPCODE_EM_TRANSMITTER_TEST 0x11 +#define HCI_OPCODE_EM_TRANSMITTER_TEST_END 0x12 -#define HCI_OPCODE_EM_WRITE_PATCH_START (0xFC27) -#define HCI_OPCODE_EM_WRITE_PATCH_CONTINUE (0xFC28) -#define HCI_OPCODE_EM_WRITE_PATCH_ABORT (0xFC29) -#define HCI_OPCODE_EM_CPU_RESET (0xFC32) +// EM9301 vendor opcodes +#define HCI_OPCODE_EM_WRITE_DATA 0x00 +#define HCI_OPCODE_EM_READ_DATA 0x01 +#define HCI_OPCODE_EM_SET_OPERATING_STATE 0x03 +#define HCI_OPCODE_EM_WRITE_PROGRAM 0x80 // only in IPS mode available +#define HCI_OPCODE_EM_CALC_CRC_CODE 0x81 // only in IPS mode available + +// EM9304 vendor opcodes +#define HCI_OPCODE_EM_WRITE_PATCH_START 0x27 +#define HCI_OPCODE_EM_WRITE_PATCH_CONTINUE 0x28 +#define HCI_OPCODE_EM_WRITE_PATCH_ABORT 0x29 +#define HCI_OPCODE_EM_SET_MEMORY_MODE 0x2B +#define HCI_OPCODE_EM_SET_SLEEP_OPTIONS 0x2D +#define HCI_OPCODE_EM_CPU_RESET 0x32 +#define HCI_OPCODE_EM_PATCH_QUERY 0x34 /** * @param bd_addr */ const hci_cmd_t hci_vendor_em_set_public_address = { - 0xFC02, "B" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_SET_PUBLIC_ADDRESS), "B" }; /** * @param baud_rate_index */ const hci_cmd_t hci_vendor_em_set_uart_baudrate = { - 0xFC07, "1" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_SET_UART_BAUD_RATE), "1" }; /** @@ -82,20 +96,20 @@ const hci_cmd_t hci_vendor_em_set_uart_baudrate = { * @param packet_payload_type */ const hci_cmd_t hci_vendor_em_transmitter_test = { - 0xFC11, "1111" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_TRANSMITTER_TEST), "1111" }; /** */ const hci_cmd_t hci_vendor_em_transmitter_test_end = { - 0xFC12, "" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_TRANSMITTER_TEST_END), "" }; /** * @param patch_index */ const hci_cmd_t hci_vendor_em_patch_query = { - 0xFC34, "2" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_PATCH_QUERY), "2" }; /** @@ -103,33 +117,40 @@ const hci_cmd_t hci_vendor_em_patch_query = { * @param memory_attribute */ const hci_cmd_t hci_vendor_em_set_memory_mode = { - 0xFC2B, "1" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_SET_MEMORY_MODE), "1" }; /** * @param sleep_option_settings */ const hci_cmd_t hci_vendor_em_set_sleep_options = { - 0xFC2D, "1" + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_SET_SLEEP_OPTIONS), "1" +}; + +/** + * @param operating_state_settings + */ +const hci_cmd_t hci_vendor_em_set_operating_state = { + HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_SET_OPERATING_STATE), "1" }; // baudrate to index for hci_vendor_em_set_uart_baudrate static const uint32_t baudrates[] = { - 0, - 0, - 0, - 9600, - 14400, - 19200, - 28800, - 38400, - 57600, - 76800, - 115200, - 230400, - 460800, - 921600, - 1843200, + 0, + 0, + 0, + 9600, + 14400, + 19200, + 28800, + 38400, + 57600, + 76800, + 115200, + 230400, + 460800, + 921600, + 1843200, }; #ifdef HAVE_EM9304_PATCH_CONTAINER @@ -138,83 +159,83 @@ extern const uint8_t container_blob_data[]; extern const uint32_t container_blob_size; static uint32_t container_blob_offset = 0; -static uint32_t container_end; // current container +static uint32_t container_end; // current container static uint16_t patch_sequence_number; static int em_cpu_reset_sent; static enum { - UPLOAD_IDLE, - UPLOAD_ACTIVE, + UPLOAD_IDLE, + UPLOAD_ACTIVE, } upload_state; // CRC32 implementation using 4-bit lookup table created by pycrc v0.9.1, https://pycrc.org // ./pycrc.py --model crc-32 --algorithm table-driven --table-idx-width=4 --generate c static const uint32_t crc32_table[16] = { - 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, - 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c + 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; static uint32_t btstack_crc32(const uint8_t *buf, uint16_t size){ - uint16_t pos; - uint32_t crc = 0xffffffff; - for (pos=0 ; pos> 4); tbl_idx = crc ^ (buf[pos] >> 4); crc = crc32_table[tbl_idx & 0x0f] ^ (crc >> 4); } - return ~crc; + return ~crc; } #endif static void chipset_set_bd_addr_command(bd_addr_t addr, uint8_t *hci_cmd_buffer){ - little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x02)); + little_endian_store_16(hci_cmd_buffer, 0, hci_vendor_em_set_public_address.opcode); hci_cmd_buffer[2] = 0x06; reverse_bd_addr(addr, &hci_cmd_buffer[3]); } static void chipset_set_baudrate_command(uint32_t baudrate, uint8_t *hci_cmd_buffer){ - // lookup baudrates - int i; - int found = 0; - for (i=0 ; i < sizeof(baudrates)/sizeof(uint32_t) ; i++){ - if (baudrates[i] == baudrate){ - found = i; - break; - } - } - if (!found){ - log_error("Baudrate %u not found in table", baudrate); - return; - } - little_endian_store_16(hci_cmd_buffer, 0, OPCODE(OGF_VENDOR, 0x07)); + // lookup baudrates + int i; + int found = 0; + for (i=0 ; i < sizeof(baudrates)/sizeof(uint32_t) ; i++){ + if (baudrates[i] == baudrate){ + found = i; + break; + } + } + if (!found){ + log_error("Baudrate %u not found in table", baudrate); + return; + } + little_endian_store_16(hci_cmd_buffer, 0, hci_vendor_em_set_uart_baudrate.opcode); hci_cmd_buffer[2] = 0x01; hci_cmd_buffer[3] = i; } #ifdef HAVE_EM9304_PATCH_CONTAINER -static void chipset_init(const void * config){ - UNUSED(config); - container_blob_offset = 0; - em_cpu_reset_sent = 0; - upload_state = UPLOAD_IDLE; +static void chipset_em9304_init(const void * config){ + UNUSED(config); + container_blob_offset = 0; + em_cpu_reset_sent = 0; + upload_state = UPLOAD_IDLE; } -static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){ - log_info("pos %u, container end %u, blob size %u", container_blob_offset, container_end, container_blob_size); +static btstack_chipset_result_t chipset_em9304_next_command(uint8_t * hci_cmd_buffer){ + log_info("pos %u, container end %u, blob size %u", container_blob_offset, container_end, container_blob_size); if (container_blob_offset >= container_blob_size) { - if (0 == em_cpu_reset_sent){ - // send EM CPU Reset - little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_CPU_RESET); - hci_cmd_buffer[2] = 0; - em_cpu_reset_sent = 1; - return BTSTACK_CHIPSET_VALID_COMMAND; - } else { - return BTSTACK_CHIPSET_DONE; - } + if (0 == em_cpu_reset_sent){ + // send EM CPU Reset + little_endian_store_16(hci_cmd_buffer, 0, HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_CPU_RESET)); + hci_cmd_buffer[2] = 0; + em_cpu_reset_sent = 1; + return BTSTACK_CHIPSET_VALID_COMMAND; + } else { + return BTSTACK_CHIPSET_DONE; + } } uint32_t tag; @@ -222,67 +243,190 @@ static btstack_chipset_result_t chipset_next_command(uint8_t * hci_cmd_buffer){ uint32_t crc; uint32_t container_size; - switch (upload_state){ - case UPLOAD_IDLE: - // check for 'em93' tag - tag = little_endian_read_32(container_blob_data, container_blob_offset); - if (0x656d3933 != tag) { - log_error("Expected 0x656d3933 ('em934') but got %08x", (int) tag); - return BTSTACK_CHIPSET_DONE; - } - // fetch info for current container - container_size = little_endian_read_32(container_blob_data, container_blob_offset + 4); - container_end = container_blob_offset + container_size; - // start uploading (<= 59 bytes) - patch_sequence_number = 1; - bytes_to_upload = btstack_min(59, container_end - container_blob_offset); - crc = btstack_crc32(&container_blob_data[container_blob_offset], bytes_to_upload); - log_info("Container type 0x%02x, id %u, build nr %u, user build nr %u, size %u", - (int) container_blob_data[container_blob_offset+9], - (int) container_blob_data[container_blob_offset+10], - (int) little_endian_read_16(container_blob_data, container_blob_offset+12), - (int) little_endian_read_16(container_blob_data, container_blob_offset+14), - (int) container_size); - // build command - little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_WRITE_PATCH_START); - hci_cmd_buffer[2] = 5 + bytes_to_upload; - hci_cmd_buffer[3] = 0; // upload to iRAM1 - little_endian_store_32(hci_cmd_buffer, 4, crc); - memcpy(&hci_cmd_buffer[8], &container_blob_data[container_blob_offset], bytes_to_upload); - container_blob_offset += bytes_to_upload; - if (container_blob_offset < container_end){ - upload_state = UPLOAD_ACTIVE; - } - return BTSTACK_CHIPSET_VALID_COMMAND; - case UPLOAD_ACTIVE: - // Upload next segement - bytes_to_upload = btstack_min(58, container_end - container_blob_offset); - crc = btstack_crc32(&container_blob_data[container_blob_offset], bytes_to_upload); - // build command - little_endian_store_16(hci_cmd_buffer, 0, HCI_OPCODE_EM_WRITE_PATCH_CONTINUE); - hci_cmd_buffer[2] = 6 + bytes_to_upload; - little_endian_store_16(hci_cmd_buffer, 3, patch_sequence_number++); - little_endian_store_32(hci_cmd_buffer, 5, crc); - memcpy(&hci_cmd_buffer[9], &container_blob_data[container_blob_offset], bytes_to_upload); - container_blob_offset += bytes_to_upload; - if (container_blob_offset >= container_end){ - log_info("container done maybe another one"); - upload_state = UPLOAD_IDLE; - } - return BTSTACK_CHIPSET_VALID_COMMAND; - } - return BTSTACK_CHIPSET_DONE; + switch (upload_state){ + case UPLOAD_IDLE: + // check for 'em93' tag + tag = little_endian_read_32(container_blob_data, container_blob_offset); + if (0x656d3933 != tag) { + log_error("Expected 0x656d3933 ('em934') but got %08x", (int) tag); + return BTSTACK_CHIPSET_DONE; + } + // fetch info for current container + container_size = little_endian_read_32(container_blob_data, container_blob_offset + 4); + container_end = container_blob_offset + container_size; + // start uploading (<= 59 bytes) + patch_sequence_number = 1; + bytes_to_upload = btstack_min(59, container_end - container_blob_offset); + crc = btstack_crc32(&container_blob_data[container_blob_offset], bytes_to_upload); + log_info("Container type 0x%02x, id %u, build nr %u, user build nr %u, size %u", + (int) container_blob_data[container_blob_offset+9], + (int) container_blob_data[container_blob_offset+10], + (int) little_endian_read_16(container_blob_data, container_blob_offset+12), + (int) little_endian_read_16(container_blob_data, container_blob_offset+14), + (int) container_size); + // build command + little_endian_store_16(hci_cmd_buffer, 0, HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_WRITE_PATCH_START)); + hci_cmd_buffer[2] = 5 + bytes_to_upload; + hci_cmd_buffer[3] = 0; // upload to iRAM1 + little_endian_store_32(hci_cmd_buffer, 4, crc); + memcpy(&hci_cmd_buffer[8], &container_blob_data[container_blob_offset], bytes_to_upload); + container_blob_offset += bytes_to_upload; + if (container_blob_offset < container_end){ + upload_state = UPLOAD_ACTIVE; + } + return BTSTACK_CHIPSET_VALID_COMMAND; + case UPLOAD_ACTIVE: + // Upload next segement + bytes_to_upload = btstack_min(58, container_end - container_blob_offset); + crc = btstack_crc32(&container_blob_data[container_blob_offset], bytes_to_upload); + // build command + little_endian_store_16(hci_cmd_buffer, 0, HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_WRITE_PATCH_CONTINUE)); + hci_cmd_buffer[2] = 6 + bytes_to_upload; + little_endian_store_16(hci_cmd_buffer, 3, patch_sequence_number++); + little_endian_store_32(hci_cmd_buffer, 5, crc); + memcpy(&hci_cmd_buffer[9], &container_blob_data[container_blob_offset], bytes_to_upload); + container_blob_offset += bytes_to_upload; + if (container_blob_offset >= container_end){ + log_info("container done maybe another one"); + upload_state = UPLOAD_IDLE; + } + return BTSTACK_CHIPSET_VALID_COMMAND; + } + return BTSTACK_CHIPSET_DONE; } #endif +#ifdef HAVE_EM9301_PATCH_CONTAINER + +/* Number of ROW in patch file [0-63] */ +#define NUMBER_OF_ROWS 64 + +/* Number of Bytes Per ROW in patch file [0-63] */ +#define ROW_SIZE 48 + +/* Number of Sectors [0-17] in patch file [0-63] */ +#define NUMBER_OF_SECTORS 2 + +extern const uint8_t EMPatchArray[]; +extern const uint32_t EMPatchArray_size; + +static signed char currentRow; +static signed char currentSector; + +typedef enum { + PATCH_LOAD_STATE_NOTSTARTED = 0, + PATCH_LOAD_STATE_ENTERINGISPMODE, + PATCH_LOAD_STATE_LOADING, + PATCH_LOAD_STATE_EXITINGISPMODE, + PATCH_LOAD_STATE_DONE +} EM9301_PATCH_STATE; + +static EM9301_PATCH_STATE patchLoadingState; + +void em9301_hardware_error(uint8_t error){ + //TODO: Stack is freezing, wait how to continue + if (patchLoadingState == PATCH_LOAD_STATE_LOADING && error == 0x80) { + return; // everything ok + } + //TODO: something is wrong +} + +static void chipset_em9301_init(const void * config){ + UNUSED(config); + + currentRow = NUMBER_OF_ROWS - 1; + currentSector = NUMBER_OF_SECTORS - 1; + + patchLoadingState = PATCH_LOAD_STATE_NOTSTARTED; + + hci_set_hardware_error_callback(&em9301_hardware_error); +} + +static btstack_chipset_result_t chipset_em9301_next_command(uint8_t * hci_cmd_buffer){ + log_info("current row %d, current sector %d, blob size %u", currentRow, currentSector, EMPatchArray_size); + + switch (patchLoadingState) + { + case PATCH_LOAD_STATE_NOTSTARTED: + /* we have not yet loading the patch, start the + loading procedure now + try to enter in ISP mode by sending HCI command + HCI_EM_Write_Data with parameters (address=0x1FFE, data=0x0000).*/ + patchLoadingState = PATCH_LOAD_STATE_ENTERINGISPMODE; + + little_endian_store_16(hci_cmd_buffer, 0, HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_WRITE_DATA)); + hci_cmd_buffer[2] = 4; + little_endian_store_16(hci_cmd_buffer, 3, 0x1FFE); + little_endian_store_16(hci_cmd_buffer, 5, 0x0000); + + return BTSTACK_CHIPSET_VALID_COMMAND; + + case PATCH_LOAD_STATE_ENTERINGISPMODE: + patchLoadingState = PATCH_LOAD_STATE_LOADING; + // send EM CPU Reset + little_endian_store_16(hci_cmd_buffer, 0, hci_reset.opcode); + hci_cmd_buffer[2] = 0; + + return BTSTACK_CHIPSET_VALID_COMMAND; + + case PATCH_LOAD_STATE_LOADING: + + if (currentSector < 0) { + /* We have now finish to load the patch it is now time to exiting ISP mode + try to exit in ISP mode by sending HCI command HCI_EM_Write_Data with parameters (address=0x1FFE, data=0x55AA).*/ + patchLoadingState = PATCH_LOAD_STATE_EXITINGISPMODE; + + little_endian_store_16(hci_cmd_buffer, 0, HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_WRITE_DATA)); + hci_cmd_buffer[2] = 4; + little_endian_store_16(hci_cmd_buffer, 3, 0x1FFE); + little_endian_store_16(hci_cmd_buffer, 5, 0x55AA); + + return BTSTACK_CHIPSET_VALID_COMMAND; + } + + little_endian_store_16(hci_cmd_buffer, 0, HCI_CMD_OPCODE(OGF_VENDOR, HCI_OPCODE_EM_WRITE_PROGRAM)); + hci_cmd_buffer[2] = ROW_SIZE + 2; + hci_cmd_buffer[3] = currentRow; + hci_cmd_buffer[4] = currentSector; + memcpy(&hci_cmd_buffer[5], &EMPatchArray[(ROW_SIZE * currentRow) + (NUMBER_OF_ROWS * ROW_SIZE * currentSector)], ROW_SIZE); + + if (currentRow == 0) { + currentRow = NUMBER_OF_ROWS - 1; + currentSector--; + } else { + currentRow--; + } + + return BTSTACK_CHIPSET_VALID_COMMAND; + + case PATCH_LOAD_STATE_EXITINGISPMODE: + patchLoadingState = PATCH_LOAD_STATE_DONE; + // send EM CPU Reset + little_endian_store_16(hci_cmd_buffer, 0, hci_reset.opcode); + hci_cmd_buffer[2] = 0; + return BTSTACK_CHIPSET_WARMSTART_REQUIRED; + + case PATCH_LOAD_STATE_DONE: + return BTSTACK_CHIPSET_DONE; + } + return BTSTACK_CHIPSET_DONE; +} + +#endif + static const btstack_chipset_t btstack_chipset_em9301 = { "EM9301", #ifdef HAVE_EM9304_PATCH_CONTAINER - chipset_init, - chipset_next_command, + chipset_em9304_init, + chipset_em9304_next_command, +#else +#ifdef HAVE_EM9301_PATCH_CONTAINER + chipset_em9301_init, + chipset_em9301_next_command, #else NULL, NULL, +#endif #endif chipset_set_baudrate_command, chipset_set_bd_addr_command, diff --git a/chipset/em9301/btstack_chipset_em9301.h b/chipset/em9301/btstack_chipset_em9301.h index 053f7dbd78..5871209a87 100644 --- a/chipset/em9301/btstack_chipset_em9301.h +++ b/chipset/em9301/btstack_chipset_em9301.h @@ -63,6 +63,10 @@ extern const hci_cmd_t hci_vendor_em_transmitter_test_end; extern const hci_cmd_t hci_vendor_em_patch_query; extern const hci_cmd_t hci_vendor_em_set_memory_mode; extern const hci_cmd_t hci_vendor_em_set_sleep_options; +extern const hci_cmd_t hci_vendor_em_set_operating_state; + +#define HCI_SUBEVENT_EM_STANDBY_STATE 0x01 +#define HCI_SUBEVENT_EM_BLE_IDLE_ENTERED 0x02 #if defined __cplusplus } diff --git a/platform/embedded/btstack_em9304_spi_embedded.c b/platform/embedded/btstack_em9304_spi_embedded.c index 85318bb447..b0dcd02693 100644 --- a/platform/embedded/btstack_em9304_spi_embedded.c +++ b/platform/embedded/btstack_em9304_spi_embedded.c @@ -145,7 +145,7 @@ static void btstack_em9304_spi_embedded_set_transfer_done_callback(void (*callba /** * @brief Poll READY state */ -static int btstack_em9304_spi_embedded_get_ready(){ +static int btstack_em9304_spi_embedded_get_ready(void){ return hal_em9304_spi_get_ready(); } diff --git a/platform/embedded/hal_em9304_spi.h b/platform/embedded/hal_em9304_spi.h index c7a7b9e2db..cec539109f 100644 --- a/platform/embedded/hal_em9304_spi.h +++ b/platform/embedded/hal_em9304_spi.h @@ -87,7 +87,7 @@ void hal_em9304_spi_disable_ready_interrupt(void); /** * @brief Poll READY state */ -int hal_em9304_spi_get_ready(); +int hal_em9304_spi_get_ready(void); /** * @brief Set Chip Selet diff --git a/platform/embedded/hal_uart_dma.h b/platform/embedded/hal_uart_dma.h index f3d5a3aeed..315f0d04e6 100644 --- a/platform/embedded/hal_uart_dma.h +++ b/platform/embedded/hal_uart_dma.h @@ -61,6 +61,11 @@ extern "C" { */ void hal_uart_dma_init(void); +/** + * @brief Deinit and close device + */ +void hal_uart_dma_deinit(void); + /** * @brief Set callback for block received - can be called from ISR context * @param callback diff --git a/platform/freertos/btstack_run_loop_freertos.c b/platform/freertos/btstack_run_loop_freertos.c index 3052300946..c2fbcf3964 100644 --- a/platform/freertos/btstack_run_loop_freertos.c +++ b/platform/freertos/btstack_run_loop_freertos.c @@ -52,7 +52,7 @@ #include "btstack_linked_list.h" #include "btstack_debug.h" #include "btstack_util.h" -#include "hal_time_ms.h" +#include // some SDKs, e.g. esp-idf, place FreeRTOS headers into an 'freertos' folder to avoid name collisions (e.g. list.h, queue.h, ..) // wih this flag, the headers are properly found diff --git a/platform/freertos/btstack_uart_block_freertos.c b/platform/freertos/btstack_uart_block_freertos.c index eeba24e490..68aced341e 100644 --- a/platform/freertos/btstack_uart_block_freertos.c +++ b/platform/freertos/btstack_uart_block_freertos.c @@ -48,7 +48,7 @@ #include "btstack_debug.h" #include "btstack_uart_block.h" #include "btstack_run_loop_freertos.h" -#include "hal_uart_dma.h" +#include #ifdef HAVE_FREERTOS_INCLUDE_PREFIX #include "freertos/FreeRTOS.h" @@ -126,9 +126,11 @@ static int btstack_uart_block_freertos_open(void){ } static int btstack_uart_block_freertos_close(void){ - // close device // ... +#ifdef HAL_UART_DMA_DEINIT + hal_uart_dma_deinit(); +#endif return 0; } diff --git a/src/bluetooth.h b/src/bluetooth.h index 55ab64ebdb..9cc5962bb2 100644 --- a/src/bluetooth.h +++ b/src/bluetooth.h @@ -380,7 +380,7 @@ typedef enum { #define OGF_LE_CONTROLLER 0x08 #define OGF_VENDOR 0x3f - +#define HCI_CMD_OPCODE(ogf, ocf) ((ocf) | ((ogf) << 10)) /** diff --git a/src/hci.c b/src/hci.c index b61d0edbfd..cb1dad1e2d 100644 --- a/src/hci.c +++ b/src/hci.c @@ -1563,6 +1563,16 @@ static void hci_initializing_event_handler(uint8_t * packet, uint16_t size){ } } +#ifdef HAVE_EM9301_PATCH_CONTAINER + // EM9301 is in ISP mode + if ((hci_stack->substate == HCI_INIT_W4_CUSTOM_INIT) + && (hci_event_packet_get_type(packet) == HCI_EVENT_HARDWARE_ERROR) + && (packet[2] == 0x80)){ + // continue processing due normal behavior + command_completed = 1; + } +#endif + #if !defined(HAVE_PLATFORM_IPHONE_OS) && !defined (HAVE_HOST_CONTROLLER_API) // Vendor == CSR diff --git a/src/hci_transport_h5.c b/src/hci_transport_h5.c index 8a5c40e913..4f01e6b3dd 100644 --- a/src/hci_transport_h5.c +++ b/src/hci_transport_h5.c @@ -738,7 +738,7 @@ static void hci_transport_h5_read_next_byte(void){ // track time receiving SLIP frame static uint32_t hci_transport_h5_receive_start; -static void hci_transport_h5_block_received(){ +static void hci_transport_h5_block_received(void){ if (hci_transport_h5_active == 0) return; // track start time when receiving first byte // a bit hackish