diff --git a/Makefile b/Makefile index c451cf962..dba449c52 100644 --- a/Makefile +++ b/Makefile @@ -58,7 +58,7 @@ ALL = $(TARGETS) $(TESTS:.c=.srec) $(TESTS:.c=.bin) $(TESTS:.c=.dis) .PRECIOUS: $(COBJS) $(TARGETS) $(TESTS:.c=.obj) -all: $(ALL) +all: $(COBJS) $(ALL) %.srec: %.obj $(OBJCOPY) ${OBJCFLAGS} -O srec $< $@ diff --git a/TODO b/TODO new file mode 100644 index 000000000..53791b68f --- /dev/null +++ b/TODO @@ -0,0 +1,9 @@ +- write routine that compares registers before and after radioinit and + prints differences + +- get the simulator in IAR working (or qemu) and check out what is + going on there. + +- all of the objects in src (src/*.o) get linked into the final objects + even if they are not used. This should be fixed. + diff --git a/boot.lds b/boot.lds index b800cb3c9..c9f49a561 100644 --- a/boot.lds +++ b/boot.lds @@ -32,6 +32,7 @@ SECTIONS . = ALIGN(4); .text : { + *(startup) *(.text) } diff --git a/doc/cal1.dump b/doc/cal1.dump new file mode 100644 index 000000000..486737c12 --- /dev/null +++ b/doc/cal1.dump @@ -0,0 +1,11 @@ +(gdb) x/40x 0x4051e4 +0x4051e4 : 0x80003048 0x00000f78 0x8000304c 0x00607707 +0x4051f4 : 0x00000000 0x000161a8 0x8000a050 0x0000047b +0x405204 : 0x8000a054 0x0000007b 0x00005dc0 0x00000000 +0x405214 : 0x00000000 0x00000000 0x00000000 0x00000000 +0x405224 : 0x00000000 0x80009400 0x00000017 0x8000a050 +0x405234 : 0x00000000 0x8000a054 0x00000000 0x80003048 +0x405244 : 0x00000f00 0x00000000 0x00000000 0x10000108 +0x405254 : 0x03180002 0x00042000 0x30000528 0x07380006 +0x405264 : 0x0000fd01 0xc60081ff 0xb90f0000 0xc51e0000 +0x405274: 0x00901200 0x05030080 0x00900480 0x00010180 diff --git a/doc/caldump.txt b/doc/caldump.txt new file mode 100644 index 000000000..302698d60 --- /dev/null +++ b/doc/caldump.txt @@ -0,0 +1,85 @@ +0x4051b4 is the base that all the radioinit entries get offset from + + +r7 base +(gdb) x/128x $r7 +0x4051b4 : 0x80009000 0x80050300 0x80009004 0x00000101 +0x4051c4 : 0x80009008 0x00000000 0x8000900c 0x00000000 +0x4051d4 : 0x80009020 0x0000000c 0x80009000 0xc0050300 +0x4051e4 : 0x80003048 0x00000f78 0x8000304c 0x00607707 +0x4051f4 : 0x00000000 0x000161a8 0x8000a050 0x0000047b +0x405204 : 0x8000a054 0x0000007b 0x00005dc0 0x00000000 +0x405214 : 0x00000000 0x00000000 0x00000000 0x00000000 +0x405224 : 0x00000000 0x80009400 0x00000017 0x8000a050 +0x405234 : 0x00000000 0x8000a054 0x00000000 0x80003048 +0x405244 : 0x00000f00 0x00000000 0x00000000 0x10000108 +0x405254 : 0x03180002 0x00042000 0x30000528 0x07380006 +0x405264 : 0x0000fd01 0xc60081ff 0xb90f0000 ---Type to continue, or q to quit--- +0xc51e0000 +0x405274: 0x00901200 0x05030080 0x00900480 0x00010180 +0x405284: 0x00900800 0x0300fc80 0x8000900c 0x200400fc +0x405294: 0x0c800090 0x901500fc 0x03008000 0x3048c005 +0x4052a4: 0x0f788000 0x304c0000 0x77078000 0x1000fb60 +0x4052b4: 0x000161a8 0x8000a050 0x0000047b 0x8000a054 +0x4052c4: 0x0300e07b 0x17800094 0x500300fd 0xfc8000a0 +0x4052d4: 0xa0540300 0x00fc8000 0x00304805 0xf60f0080 +0x4052e4: 0x01081400 0x00021000 0x20000318 0x05280004 +0x4052f4: 0x00063000 0x00010738 0x00000000 0x00000000 +0x405304: 0x00000000 0x00000000 0x00000000 0x00000000 + + +(gdb) x/128x $r4 +0x402b54 : 0x80003000 0x00000019 0x80003048 0x00000ffb +0x402b64 : 0x80003000 0x00000018 0x80003048 0x00000f04 +0x402b74 : 0x00000000 0x000161a8 0x80003048 0x00000ffc +0x402b84 : 0x80009000 0x80050100 0x80009400 0x00020017 +0x402b94 : 0x80009a04 0x8185a0a4 0x80009a00 0x8c900025 +0x402ba4 : 0x00000000 0x00011194 0x80009a00 0x8c900021 +0x402bb4 : 0x80009a00 0x8c900027 0x00000000 0x00011194 +0x402bc4 : 0x80009a00 0x8c90002b 0x80009a00 0x8c90002f +0x402bd4 : 0x00000000 0x00011194 0x80009a00 0x8c900000 +0x402be4 : 0x80009000 0x80050300 0x80004118 0x00180012 +0x402bf4 : 0x80009204 0x00000605 0x80009208 0x00000504 +0x402c04 : 0x8000920c 0x00001111 ---Type to continue, or q to quit--- +0x80009210 0x0fc40000 +0x402c14 : 0x80009300 0x20046000 0x80009304 0x4005580c +0x402c24 : 0x80009308 0x40075801 0x8000930c 0x4005d801 +0x402c34 : 0x80009310 0x5a45d800 0x80009314 0x4a45d800 +0x402c44 : 0x80009318 0x40044000 0x80009380 0x00106000 +0x402c54 : 0x80009384 0x00083806 0x80009388 0x00093807 +0x402c64 : 0x8000938c 0x0009b804 0x80009390 0x000db800 +0x402c74 : 0x80009394 0x00093802 0x8000a008 0x00000015 +0x402c84 : 0x8000a018 0x00000002 0x8000a01c 0x0000000f +0x402c94 : 0x80009424 0x0000aaa0 0x80009434 0x01002020 +0x402ca4 : 0x80009438 0x016800fe 0x8000943c 0x8e578248 +0x402cb4 : 0x80009440 0x000000dd 0x80009444 0x00000946 +---Type to continue, or q to quit--- +0x402cc4 : 0x80009448 0x0000035a 0x8000944c 0x00100010 +0x402cd4 : 0x80009450 0x00000515 0x80009460 0x00397feb +0x402ce4 : 0x80009464 0x00180358 0x8000947c 0x00000455 +0x402cf4 : 0x800094e0 0x00000001 0x800094e4 0x00020003 +0x402d04 : 0x800094e8 0x00040014 0x800094ec 0x00240034 +0x402d14 : 0x800094f0 0x00440144 0x800094f4 0x02440344 +0x402d24 : 0x800094f8 0x04440544 0x80009470 0x0ee7fc00 +0x402d34 : 0x8000981c 0x00000082 0x80009828 0x0000002a +0x402d44 : 0x0006b5f8 0x0015000c 0x21fa4f39 0xf7fd0089 + + +(gdb) x/128x $r5 +0x405210 : 0x00000000 0x00000000 0x00000000 0x00000000 +0x405220 : 0x00000000 0x00000000 0x80009400 0x00000017 +0x405230 : 0x8000a050 0x00000000 0x8000a054 0x00000000 +0x405240 : 0x80003048 0x00000f00 0x00000000 0x00000000 +0x405250 : 0x10000108 0x03180002 0x00042000 0x30000528 +0x405260 : 0x07380006 0x0000fd01 0xc60081ff 0xb90f0000 +0x405270: 0xc51e0000 0x00901200 0x05030080 0x00900480 +0x405280: 0x00010180 0x00900800 0x0300fc80 0x8000900c +0x405290: 0x200400fc 0x0c800090 0x901500fc 0x03008000 +0x4052a0: 0x3048c005 0x0f788000 0x304c0000 0x77078000 +0x4052b0: 0x1000fb60 0x000161a8 0x8000a050 0x0000047b +0x4052c0: 0x8000a054 0x0300e07b 0x17800094 0x500300fd +0x4052d0: 0xfc8000a0 0xa0540300 0x00fc8000 0x00304805 +0x4052e0: 0xf60f0080 0x01081400 0x00021000 0x20000318 +0x4052f0: 0x05280004 0x00063000 0x00010738 0x00000000 +0x405300: 0x00000000 0x00000000 0x00000000 0x00000000 +0x405310: 0x00000000 0x00000000 0x00000000 0x00000000 diff --git a/doc/mc13224v.img b/doc/mc13224v.img new file mode 100644 index 000000000..c5e514380 Binary files /dev/null and b/doc/mc13224v.img differ diff --git a/doc/radioinit b/doc/radioinit new file mode 100644 index 000000000..9335b3ed5 --- /dev/null +++ b/doc/radioinit @@ -0,0 +1,274 @@ +Entries in ram are processed by SMACinitfrommemory and executeentry +(which does the work). I suspect that these entries are loaded in from +the rom from the rom_data_init call in the beginning stub. For now +we'll do the simple thing of performing the actions they do, but for +real it would be better to load out from ROM and execute the entries +in a similar way. That way, if the cal data changes in the ROM, our +code should still work. + +When radioinit first starts it seems to do checks for a 24MHZ clock +and if the buck should be enabled. Assuming 24MHZ and no buck the next +things it does is 5 entries in cal1 (40 bytes, 4 bytes per word, = 10 +words, 2 words per entry = 5 entrys) + +0x80003048 +0x00000f78 + +0x8000304c +0x00607707 + +the next entry is zero addr with val 0x000161a8... this is a delay +entry. Loop here 0x000161a8 times. then return. + +0x00000000 +0x000161a8 + +Then two more memory stuffs: + +0x8000a050 +0x0000047b + +0x8000a054 +0x0000007b + +then it seems like the emulator dies on the stack munging they do at +the end of InitFromMemory... but I think I've decoded the entry +enough to figure out the rest. + +then they do one entry of r4 base + 48 (gRadioTOCCal2_24MHz_c[0]) + +0x80009000 +0x80050100 + +then they do 11 entries in cal3 and reg replacment (first two have delays) + +0x402b8c : 0x80009400 0x00020017 0x80009a04 0x8185a0a4 +0x402b9c : 0x80009a00 0x8c900025 0x00000000 0x00011194 +0x402bac : 0x80009a00 0x8c900021 0x80009a00 0x8c900027 +0x402bbc : 0x00000000 0x00011194 0x80009a00 0x8c90002b +0x402bcc : 0x80009a00 0x8c90002f 0x00000000 0x00011194 +0x402bdc : 0x80009a00 0x8c900000 + +then 4 entries from r5+24 (buffer_radio_init and cal5) + +0x80009400 0x00000017 +0x405230 : 0x8000a050 0x00000000 0x8000a054 0x00000000 +0x405240 : 0x80003048 0x00000f00 + +then 43 entries from r4+152 (reg replacement) + +0x402bec : 0x80004118 0x00180012 0x80009204 0x00000605 +0x402bfc : 0x80009208 0x00000504 0x8000920c 0x00001111 +0x402c0c : 0x80009210 0x0fc40000 0x80009300 0x20046000 +0x402c1c : 0x80009304 0x4005580c 0x80009308 0x40075801 +0x402c2c : 0x8000930c 0x4005d801 0x80009310 0x5a45d800 +0x402c3c : 0x80009314 0x4a45d800 0x80009318 0x40044000 +0x402c4c : 0x80009380 0x00106000 0x80009384 0x00083806 +0x402c5c : 0x80009388 0x00093807 0x8000938c 0x0009b804 +0x402c6c : 0x80009390 0x000db800 0x80009394 0x00093802 +0x402c7c : 0x8000a008 0x00000015 0x8000a018 0x00000002 +0x402c8c : 0x8000a01c 0x0000000f 0x80009424 0x0000aaa0 +0x402c9c : 0x80009434 0x01002020 0x80009438 0x016800fe +0x402cac : 0x8000943c 0x8e578248 0x80009440 0x000000dd +0x402cbc : 0x80009444 0x00000946 0x80009448 0x0000035a +0x402ccc : 0x8000944c 0x00100010 0x80009450 0x00000515 +0x402cdc : 0x80009460 0x00397feb 0x80009464 0x00180358 +0x402cec : 0x8000947c 0x00000455 0x800094e0 0x00000001 +0x402cfc : 0x800094e4 0x00020003 0x800094e8 0x00040014 +0x402d0c : 0x800094ec 0x00240034 0x800094f0 0x00440144 +0x402d1c : 0x800094f4 0x02440344 0x800094f8 0x04440544 +0x402d2c : 0x80009470 0x0ee7fc00 0x8000981c 0x00000082 +0x402d3c : 0x80009828 0x0000002a + +then flash init. (hrmm.. this might be important) + +then flyback init. + +then maybe buckbypass sequence... 4 entries from r4+16 + +0x402b64 : 0x80003000 0x00000018 0x80003048 0x00000f04 +0x402b74 : 0x00000000 0x000161a8 0x80003048 0x00000ffc + +RadioInit is (roughly): + + SMAC_InitFromMemory(gRadioTOCCal1,40); + SMAC_InitFromMemory(gRadioTOCCal2_24MHz_c,8); + SMAC_InitFromMemory(gRadioTOCCal3_c,88); + SMAC_InitFromMemory(gRadioTOCCal5,32); + SMAC_InitFromMemory(gRadioInit_RegReplacement_c,344); + SMAC_InitFromFlash(0x1F000); + SMAC_InitFlybackSettings(); + SMAC_InitFromMemory(gBuckByPass_c,16); + + fill_ram_struct(&u8RamValues); + + uint8_t i; + uint8_t buffer_radio_init[16]; + for(i=0; i<16; i++) { + buffer_radio_init[i] = get_ctov(i,u8RamValues[3]); + } + + +Some kind of success! + +This replacment works: + + + // RadioInit(PLATFORM_CLOCK, gDigitalClock_PN_c, u32LoopDiv); // need this to work + + /* my replacment for RadioInit, flyback and vreg have been separated out */ + radio_init(); + // SMAC_InitFromMemory(gRadioTOCCal1,40); + // *(volatile uint32_t *)0x80009000 = 0x80050100; + // SMAC_InitFromMemory(gRadioTOCCal2_24MHz_c,8); + // SMAC_InitFromMemory(gRadioTOCCal3_c,88); + // SMAC_InitFromMemory(gRadioTOCCal5,32); + // SMAC_InitFromMemory(gRadioInit_RegReplacement_c,344); +// SMAC_InitFromFlash(0x1F000); + // SMAC_InitFlybackSettings(); + flyback_init(); + // SMAC_InitFromMemory(gBuckByPass_c,16); + vreg_init(); + + *((uint32_t *)&u8RamValues) = 0x4c20030a; + fill_ram_struct(&u8RamValues); + + for(j=0; j<16; j++) { + // buffer_radio_init[j] = get_ctov(j,u8RamValues[3]); + buffer_radio_init[j] = get_ctov(j,0x4c); //0x4c loads the right values into buffer_radio_init... but why isn't RamValues correct? + } + + +Which means my radio_init, and vreg_init are good. It also means that +my intreprtation of buffer_radio_init is correct. It may also mean +that u8RamValues isn't important since I just set it's value. + +That means I only have InitFromFlash to replace now! + +Actually, I should test if that is necessary --- I still find it a +little hard to believe that they put essential data on NVM --- except +they could set codeprotect so that clods won't erase it on accident. + +See PLM/LibInterface/NVM.h for some docs. Looks like they put a +standard SST, ST, or Atmel spi flash in there (note the comment about +continuous read mode). + +MACPHY.a might use a ROM service for the flash init: + +0000f97c g F *ABS* 00000000 InitFromFlash + + ac: 4668 mov r0, sp + ae: f7ff fffe bl 0 + b2: 4669 mov r1, sp + b4: 780a ldrb r2, [r1, #0] + b6: 0001 lsls r1, r0, #0 + b8: 20f8 movs r0, #248 + ba: 0240 lsls r0, r0, #9 + bc: f7ff fffe bl 0 + +uint32_t InitFromFlash(uint32_t nvmAddress, uint32_t nLength); + +Which looks like InitFromFlash(0x1F00,?); + +Good news! It doesn't look like InitFromFlash is necessary. It might +just be a hook for them to patch the init that is grabbed from rom or +something. + +Checking if buffer_radio_init is important. If so, then I need to +figure out how it's used and, preferably, what it means. + +So buffer_radio_init is necessary for their code to work. I'm not sure +if it is necessary for the radio of if it's necessary for there app. + +Now I need to figure these out: + + (void)MLMEPAOutputAdjust(gu8CurrentPowerLevel); + MLMESetChannelRequest((channel_num_t)gu8CurrentChannel); + + +#define gPowerLevel_m30dBm_c 0x00 +#define gPowerLevel_m28dBm_c 0x01 +#define gPowerLevel_m26dBm_c 0x02 +#define gPowerLevel_m24dBm_c 0x03 +#define gPowerLevel_m22dBm_c 0x04 +#define gPowerLevel_m20dBm_c 0x05 +#define gPowerLevel_m18dBm_c 0x06 +#define gPowerLevel_m16dBm_c 0x07 +#define gPowerLevel_m14dBm_c 0x08 +#define gPowerLevel_m12dBm_c 0x09 +#define gPowerLevel_m10dBm_c 0x0a +#define gPowerLevel_m8dBm_c 0x0b +#define gPowerLevel_m6dBm_c 0x0c +#define gPowerLevel_m4dBm_c 0x0d +#define gPowerLevel_m2dBm_c 0x0e +#define gPowerLevel_0dBm_c 0x0f +#define gPowerLevel_2dBm_c 0x10 +#define gPowerLevel_4dBm_c 0x11 +#define gPowerLevel_6dBm_c 0x12 + +gu8CurrentPowerLevel is set to gPowerLevel_0dBm_c = 0x0f + +some kind of look-up table for setpower + +004037e4 : + 4037e4: 0000080f .word 0x0000080f + 4037e8: 0000080f .word 0x0000080f + 4037ec: 0000080f .word 0x0000080f + 4037f0: 0000080f .word 0x0000080f + 4037f4: 0000081f .word 0x0000081f + 4037f8: 0000081f .word 0x0000081f + 4037fc: 0000081f .word 0x0000081f + 403800: 0000080f .word 0x0000080f + 403804: 0000080f .word 0x0000080f + 403808: 0000080f .word 0x0000080f + 40380c: 0000001f .word 0x0000001f + 403810: 0000000f .word 0x0000000f + 403814: 0000000f .word 0x0000000f + 403818: 00000816 .word 0x00000816 + 40381c: 0000001b .word 0x0000001b + 403820: 0000000b .word 0x0000000b + 403824: 00000802 .word 0x00000802 + 403828: 00000817 .word 0x00000817 + 40382c: 00000003 .word 0x00000003 + +00403830 : + 403830: 000022c0 .word 0x000022c0 + 403834: 000022c0 .word 0x000022c0 + 403838: 000022c0 .word 0x000022c0 + 40383c: 00002280 .word 0x00002280 + 403840: 00002303 .word 0x00002303 + 403844: 000023c0 .word 0x000023c0 + 403848: 00002880 .word 0x00002880 + 40384c: 000029f0 .word 0x000029f0 + 403850: 000029f0 .word 0x000029f0 + 403854: 000029f0 .word 0x000029f0 + 403858: 000029c0 .word 0x000029c0 + 40385c: 00002bf0 .word 0x00002bf0 + 403860: 000029f0 .word 0x000029f0 + 403864: 000028a0 .word 0x000028a0 + 403868: 00002800 .word 0x00002800 + 40386c: 00002ac0 .word 0x00002ac0 + 403870: 00002880 .word 0x00002880 + 403874: 00002a00 .word 0x00002a00 + 403878: 00002b00 .word 0x00002b00 + +0040387c : + 40387c: 000123a0 .word 0x000123a0 + 403880: 000163a0 .word 0x000163a0 + 403884: 0001a3a0 .word 0x0001a3a0 + 403888: 0001e3a0 .word 0x0001e3a0 + 40388c: 000223a0 .word 0x000223a0 + 403890: 000263a0 .word 0x000263a0 + 403894: 0002a3a0 .word 0x0002a3a0 + 403898: 0002e3a0 .word 0x0002e3a0 + 40389c: 000323a0 .word 0x000323a0 + 4038a0: 000363a0 .word 0x000363a0 + 4038a4: 0003a3a0 .word 0x0003a3a0 + 4038a8: 0003a3a0 .word 0x0003a3a0 + 4038ac: 0003e3a0 .word 0x0003e3a0 + 4038b0: 000423a0 .word 0x000423a0 + 4038b4: 000523a0 .word 0x000523a0 + 4038b8: 000423a0 .word 0x000423a0 + 4038bc: 0004e3a0 .word 0x0004e3a0 + 4038c0: 0004e3a0 .word 0x0004e3a0 + 4038c4: 0004e3a0 .word 0x0004e3a0 diff --git a/include/maca.h b/include/maca.h new file mode 100644 index 000000000..ba263de5c --- /dev/null +++ b/include/maca.h @@ -0,0 +1,415 @@ +#ifndef _MACA_H_ +#define _MACA_H_ + +#include "embedded_types.h" + +#define MACA_BASE 0x80004000 +#define MACA_RESET 0x80004004 +#define MACA_RANDOM 0x80004008 +#define MACA_CONTROL 0x8000400c +#define MACA_STATUS 0x80004010 +#define MACA_DMARX 0x80004080 +#define MACA_DMATX 0x80004084 +#define MACA_GETRXLVL 0x80004098 +#define MACA_PREAMBLE 0x8000411c + +#define gMACA_Clock_DIV_c 95 + +//rom_base_adr equ 0x00000000 ; rom base address +//ram_base_adr equ 0x00400000 ; ram base address +//ram0_base_adr equ 0x00400000 ; ram0 base address (2K words = 8K +//bytes) +//ram1_base_adr equ 0x00402000 ; ram1 base address (6K words = 24K +//bytes) +//ram2_base_adr equ 0x00408000 ; ram2 base address (8K words = 32K +//bytes) +//ram3_base_adr equ 0x00410000 ; ram3 base address (8K words +enum { + cc_success = 0, + cc_timeout = 1, + cc_channel_busy = 2, + cc_crc_fail = 3, + cc_aborted = 4, + cc_no_ack = 5, + cc_no_data = 6, + cc_late_start = 7, + cc_ext_timeout = 8, + cc_ext_pnd_timeout = 9, + cc_nc1 = 10, + cc_nc2 = 11, + cc_nc3 = 12, + cc_cc_external_abort= 13, + cc_not_completed = 14, + cc_bus_error = 15 +}; +//control codes for mode bits + +enum { + control_mode_no_cca = 0, + control_mode_non_slotted = (1<<3), + control_mode_slotted = (1<<4) +}; +//control codes for sequence bits +enum { + control_seq_nop = 0, + control_seq_abort = 1, + control_seq_wait = 2, + control_seq_tx = 3, + control_seq_rx = 4, + control_seq_txpoll = 5, + control_seq_cca = 6, + control_seq_ed = 7 +}; + +#define maca_status_cc_mask (0x0F) + +#define maca_reset_rst (1<<0) +#define maca_reset_cln_on (1<<1) + +#define maca_frmpnd_data_pending (1<<0) +#define maca_frmpnd_no_data_pending (0x00) + +#define maca_txlen_max_rxlen (127<<16) + +#define max_rx_ackwnd_slotted_mode (0xFFF<<16) +#define max_rx_ackwnd_normal_mode (0xFFF) + + +#define control_pre_count (7<<16) /* preamble reapeat counter */ +#define control_rst_slot (1<<15) /* reset slot counter */ +#define control_role (1<<13) /* set if PAN coordinator */ +#define control_nofc (1<<12) /* set to disable FCS */ +#define control_prm (1<<11) /* set for promiscuous mode */ +#define control_relative (1<<10) /* 1 for relative, 0 for absolute */ +#define control_asap (1<<9) /* 1 start now, 0 timer start */ +#define control_bcn (1<<8) /* 1 beacon only, 0 for a */ +#define control_auto (1<<7) /* 1 continuous rx, rx only once */ +#define control_lfsr (1<<6) /* 1 use polynomial for Turbolink */ + +#define maca_irq_strt (1<<15) /* + STRT + Bit 15 + Action Started Interrupt—An auto-sequence is started, either + immediately or by timer trigger. + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_sync (1<<14) /* + SYNC + Bit 14 + Sync Detected Interrupt—The modem has detected the beginning + of a new packet + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_cm (1<<13) /* + CM + Bit 13 + Complete Clock Interrupt—The complete clock has generated a + trigger. + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_crc (1<<12) /* + CRC + Bit 12 + Checksum Failed Interrupt—The checksum failed for the received + packet. + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_flt (1<<11) /* + FLT + Bit 11 + Filter Failed Interrupt—The receive header filter failed. 1 = Clear interrupt source + 0 = Leave source untouched + SFT + Bit 10 + Soft Complete Clock Interrupt—The soft complete clock has + generated a trigger. + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_sftclk (1<<10) + +#define maca_irq_lvl (1<<9) /* + LVL + Bit 9 + FIFO Level interrupt—The receive FIFO level is reached or + exceeded. + 1 = Clear interrupt source + 0 = Leave source untouched + Bit 8-5 Reserved bits—Read as zero and written with zero for future + compatibility. N/A + */ +#define maca_irq_rst (1<<4) /* + RST + Bit 4 + Reset Interrupt—A non maskable reset interrupt detected (TBD!!!) 1 = Clear interrupt source + 0 = Leave source untouched + WU + Bit 3 + Wake-up Interrupt—Low power mode has been exited (TBD in + connection with CCM module). + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_wu (1<<3) + +#define maca_irq_di (1<<2) /* + DI + Bit 2 + Data Indication Interrupt—During receive, a packet has been + successfully received. + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_poll (1<<1) /* + POLL + Bit 1 + Poll Indication Interrupt—Issued when data request received (and + before ACK transmitted). MCU may then set MACA_FRMPND and + prepare fast response. TBD: Shall this be skipped if + MACA_FRMPND is clear? + 1 = Clear interrupt source + 0 = Leave source untouched + */ +#define maca_irq_acpl (1<<0) /* + ACPL + Action Complete Interrupt—Marks the completion of a complete + auto-sequence. + 1 = Clear interrupt source + 0 = Leave source untouched + */ + + +#define maca_start_clk (1<<0)/* + TMREN & TMRDIS enable/disable start clock + */ + +#define maca_cpl_clk (1<<1)/* + TMREN & TMRDIS enable/disable complete clock + */ + +#define maca_soft_clk (1<<2)/* + TMREN & TMRDIS enable/disable soft complete clock + */ + +#define maca_abort_start_clk (1<<3)/* + TMRDIS abort start clock + */ + +#define maca_abort_cpl_clk (1<<4)/* + TMRDIS abort complete clock + */ + +#define maca_abort_soft_clk (1<<5)/* + TMRDIS abort soft complete clock + */ + + +#define maca_version (*((volatile uint32_t *)(0x80004000))) +#define maca_reset (*((volatile uint32_t *)(0x80004004))) +#define maca_random (*((volatile uint32_t *)(0x80004008))) +#define maca_control (*((volatile uint32_t *)(0x8000400c))) +#define maca_status (*((volatile uint32_t *)(0x80004010))) +#define maca_frmpnd (*((volatile uint32_t *)(0x80004014))) + +#define maca_edvalue (*((volatile uint32_t *)(0x8000401c))) +#define maca_tmren (*((volatile uint32_t *)(0x80004040))) +#define maca_tmrdis (*((volatile uint32_t *)(0x80004044))) +#define maca_clk (*((volatile uint32_t *)(0x80004048))) +#define maca_startclk (*((volatile uint32_t *)(0x8000404c))) +#define maca_cplclk (*((volatile uint32_t *)(0x80004050))) +#define maca_sftclk (*((volatile uint32_t *)(0x80004054))) +#define maca_clkoffset (*((volatile uint32_t *)(0x80004058))) +#define maca_relclk (*((volatile uint32_t *)(0x8000405c))) +#define maca_cpltim (*((volatile uint32_t *)(0x80004060))) +#define maca_slotoffset (*((volatile uint32_t *)(0x80004064))) +#define maca_timestamp (*((volatile uint32_t *)(0x80004068))) +#define maca_dmarx (*((volatile uint32_t *)(0x80004080))) +#define maca_dmatx (*((volatile uint32_t *)(0x80004084))) +#define maca_dmatxpoll (*((volatile uint32_t *)(0x80004088))) +#define maca_txlen (*((volatile uint32_t *)(0x8000408c))) +#define maca_txseqnr (*((volatile uint32_t *)(0x80004090))) +#define maca_setrxlvl (*((volatile uint32_t *)(0x80004094))) +#define maca_getrxlvl (*((volatile uint32_t *)(0x80004098))) +#define maca_irq (*((volatile uint32_t *)(0x800040c0))) +#define maca_clrirq (*((volatile uint32_t *)(0x800040c4))) +#define maca_setirq (*((volatile uint32_t *)(0x800040c8))) +#define maca_maskirq (*((volatile uint32_t *)(0x800040cc))) +#define maca_panid (*((volatile uint32_t *)(0x80004100))) +#define maca_addr16 (*((volatile uint32_t *)(0x80004104))) +#define maca_maca64hi (*((volatile uint32_t *)(0x80004108))) +#define maca_maca64lo (*((volatile uint32_t *)(0x8000410c))) +#define maca_fltrej (*((volatile uint32_t *)(0x80004110))) +#define maca_divider (*((volatile uint32_t *)(0x80004114))) +#define maca_warmup (*((volatile uint32_t *)(0x80004118))) +#define maca_preamble (*((volatile uint32_t *)(0x8000411c))) +#define maca_whiteseed (*((volatile uint32_t *)(0x80004120))) +#define maca_framesync (*((volatile uint32_t *)(0x80004124))) +#define maca_framesync2 (*((volatile uint32_t *)(0x80004128))) +#define maca_txackdelay (*((volatile uint32_t *)(0x80004140))) +#define maca_rxackdelay (*((volatile uint32_t *)(0x80004144))) +#define maca_eofdelay (*((volatile uint32_t *)(0x80004148))) +#define maca_ccadelay (*((volatile uint32_t *)(0x8000414c))) +#define maca_rxend (*((volatile uint32_t *)(0x80004150))) +#define maca_txccadelay (*((volatile uint32_t *)(0x80004154))) +#define maca_key3 (*((volatile uint32_t *)(0x80004158))) +#define maca_key2 (*((volatile uint32_t *)(0x80004158))) +#define maca_key1 (*((volatile uint32_t *)(0x80004158))) +#define maca_key0 (*((volatile uint32_t *)(0x80004158))) + + +typedef union maca_version_reg_tag +{ + struct + { + uint32_t MINOR:8; + uint32_t RESERVED1:8; + uint32_t MAJOR:8; + uint32_t RESERVED2:8; + } Bits; + uint32_t Reg; +} maca_version_reg_t; + +#define maca_version_reg_st ((maca_version_reg_t)(maca_version)) + + +typedef union maca_reset_reg_tag +{ + struct + { + uint32_t RESERVED:30; + uint32_t CLK_ON:1; + uint32_t RST:1; + } Bits; + uint32_t Reg; +} maca_reset_reg_t; + +#define maca_reset_reg_st ((maca_reset_reg_t)(maca_reset)) + + +typedef union maca_ctrl_reg_tag +{ + struct + { + uint32_t RESERVED:11; + uint32_t ISM:1; + uint32_t PRE_COUNT:4; + uint32_t RSTO:1; + uint32_t RSV:1; + uint32_t ROLE:1; + uint32_t NOFC:1; + uint32_t PRM:1; + uint32_t rel:1; + uint32_t ASAP:1; + uint32_t BCN:1; + uint32_t AUTO:1; + uint32_t LFSR:1; + uint32_t TM:1; + uint32_t MODE:2; + uint32_t SEQUENCE:3; + } Bits; + uint32_t Reg; +} maca_ctrl_reg_t; + +#define maca_control_ism (1<<20) +#define maca_control_zigbee (~maca_control_ism) + +#define maca_ctrl_reg_st ((maca_ctrl_reg_t *)(&maca_reset)) +#define _set_maca_test_mode(x) (maca_ctrl_reg_st->Bits.TM = x) +#define _set_maca_sequence(x) (maca_ctrl_reg_st->Bits.SEQUENCE = x) +#define _set_maca_asap(x) (maca_ctrl_reg_st->Bits.ASAP = x) + + +#define MACA_CTRL_ZIGBEE_MODE (0) +#define MACA_CTRL_ISM_MODE (1) +#define MACA_CTRL_PRM_NORMAL_MODE (0) +#define MACA_CTRL_PRM_PROMISCUOUS_MODE (1) +#define MACA_CTRL_BCN_ALL (0) +#define MACA_CTRL_BCN_BEACON (1) +#define MACA_CTRL_TM_NORMAL (0) +#define MACA_CTRL_TM_TEST (1) +#define MACA_CTRL_MODE_NO_CCA (0) +#define MACA_CTRL_MODE_NON_SLOTTED (1) +#define MACA_CTRL_MODE_SLOTTED (2) + + +typedef union maca_status_reg_tag +{ + struct + { + uint32_t RESERVED:16; + uint32_t TO:1; + uint32_t CRC:1; + uint32_t BUSY:1; + uint32_t OVR:1; + uint32_t zigbee:1; + uint32_t :7; + uint32_t COMPLETE_CODE:4; + } Bits; + uint32_t Reg; +} maca_status_reg_t; + + +typedef enum maca_freq_chann_tag +{ + SMAC_CHANN_11 = 0, + SMAC_CHANN_12, + SMAC_CHANN_13, + SMAC_CHANN_14, + SMAC_CHANN_15, + SMAC_CHANN_16, + SMAC_CHANN_17, + SMAC_CHANN_18, + SMAC_CHANN_19, + SMAC_CHANN_20, + SMAC_CHANN_21, + SMAC_CHANN_22, + SMAC_CHANN_23, + SMAC_CHANN_24, + SMAC_CHANN_25, + SMAC_CHANN_26, + MAX_SMAC_CHANNELS +} maca_freq_chann_t; + + +typedef union maca_maskirq_reg_tag +{ + struct + { + uint32_t RESERVED1:16; + uint32_t STRT:1; + uint32_t SYNC:1; + uint32_t CM:1; + uint32_t CRC:1; + uint32_t FLT:1; + uint32_t SFT:1; + uint32_t LVL:1; + uint32_t RESERVED0:4; + uint32_t NOT_USED1:1; + uint32_t NOT_USED0:1; + uint32_t DI:1; + uint32_t POLL:1; + uint32_t ACPL:1; + } Bits; + uint32_t Reg; +} maca_maskirq_reg_t; + +#define _is_action_complete_interrupt(x) (0 != (maca_irq_acpl & x)) +#define _is_filter_failed_interrupt(x) (0 != (maca_irq_flt & x)) + +#define SMAC_MACA_CNTL_INIT_STATE ( control_prm | control_nofc | control_mode_non_slotted ) + +#define MACA_WRITE(reg, src) (reg = src) +#define MACA_READ(reg) reg + +void reset_maca(void); +void init_phy(void); +void ResumeMACASync(void); +void radio_init(void); +void set_power(uint8_t power); +void set_channel(uint8_t chan); + +#endif // _MACA_H_ diff --git a/qemu/README.qemu.mc1322x b/qemu/README.qemu.mc1322x index 1d43d576c..8703e0183 100644 --- a/qemu/README.qemu.mc1322x +++ b/qemu/README.qemu.mc1322x @@ -7,11 +7,14 @@ Build qemu make Run with - arm-softmmu/qemu-system-arm -S -M mc1322x -nographic -pflash /home/malvira/mc1322x-tests/tests/blink-red.bin -which will load the bin at 0x00400000 and execution will start there (type c). + arm-softmmu/qemu-system-arm -S -M mc1322x -nographic \ + foo -I plan to add a way to load a rom image as well... +which will load rom.img at 0x00000000 and ram.img at +0x00400000 --- execution will start at 0x00400000 (type c). + +I'll be adding command line options for those images soon. Debug with gdb: diff --git a/qemu/hw/mc1322x.c b/qemu/hw/mc1322x.c index 39bf026d5..d7cf600fb 100644 --- a/qemu/hw/mc1322x.c +++ b/qemu/hw/mc1322x.c @@ -11,6 +11,9 @@ #include "sysemu.h" #include "boards.h" #include "flash.h" +#include "block.h" + +#include static const int sector_len = 128 * 1024; @@ -19,6 +22,8 @@ struct mc1322x_state_s *mc1322x_init(void) { struct mc1322x_state_s *s; int index; + FILE *ram, *rom; + ram_addr_t ramoff, romoff; s = (struct mc1322x_state_s *) qemu_mallocz(sizeof(struct mc1322x_state_s)); @@ -30,18 +35,24 @@ struct mc1322x_state_s *mc1322x_init(void) register_savevm("cpu", 0, ARM_CPU_SAVE_VERSION, cpu_save, cpu_load, s->env); - /* SDRAM & Internal Memory Storage */ - cpu_register_physical_memory(MC1322X_ROMBASE, MC1322X_ROMSIZE, - qemu_ram_alloc(MC1322X_ROMSIZE) | IO_MEM_RAM); - cpu_register_physical_memory(MC1322X_RAMBASE, MC1322X_RAMSIZE, - qemu_ram_alloc(MC1322X_RAMSIZE) | IO_MEM_RAM); + /* should probably allocate memory for all the cpu registers also */ - index = drive_get_index(IF_PFLASH, 0, 0); - if (!pflash_cfi01_register(0x00400000, qemu_ram_alloc(MC1322X_RAMBASE), - drives_table[index].bdrv, sector_len, MC1322X_RAMBASE / sector_len, - 2, 0, 0, 0, 0)) { - fprintf(stderr, "qemu: Error registering flash memory.\n"); - exit(1); + romoff = qemu_ram_alloc(MC1322X_ROMSIZE); + cpu_register_physical_memory(MC1322X_ROMBASE, MC1322X_ROMSIZE, + romoff | IO_MEM_RAM); + ramoff = qemu_ram_alloc(MC1322X_RAMSIZE); + cpu_register_physical_memory(MC1322X_RAMBASE, MC1322X_RAMSIZE, + ramoff | IO_MEM_RAM); + + /* need to add a way to specify these images from the command line */ + + if(rom = fopen("rom.img", "r")) { + fread(phys_ram_base,1,MC1322X_ROMSIZE,rom); + } + + if(ram = fopen("ram.img", "r")) { + fprintf(stderr, "loading ram image\n"); + fread(phys_ram_base+ramoff,1,MC1322X_RAMSIZE,ram); } s->env->regs[15] = 0x00400000; diff --git a/qemu/hw/mc1322x.h b/qemu/hw/mc1322x.h index 1d7a36253..c2a822d50 100644 --- a/qemu/hw/mc1322x.h +++ b/qemu/hw/mc1322x.h @@ -11,7 +11,7 @@ #define MC1322X_ROMBASE 0x00000000 #define MC1322X_ROMSIZE 0x00014000 -#define MC1322X_RAMBASE 0x04000000 +#define MC1322X_RAMBASE 0x00400000 #define MC1322X_RAMSIZE 0x00020000 /* mc1322x.c */ diff --git a/src/maca.c b/src/maca.c new file mode 100644 index 000000000..cf711c973 --- /dev/null +++ b/src/maca.c @@ -0,0 +1,406 @@ +#include "maca.h" + +#define reg(x) (*(volatile uint32_t *)(x)) + +void init_phy(void) +{ + volatile uint32_t cnt; + + maca_reset = maca_reset_rst; + + for(cnt=0; cnt < 100; cnt++); + + maca_reset = maca_reset_cln_on; + maca_control = control_seq_nop; +#define DELAY 400000 + for(cnt=0; cnt < DELAY; cnt++); + + maca_tmren = maca_start_clk | maca_cpl_clk; + maca_divider = gMACA_Clock_DIV_c; + maca_warmup = 0x00180012; + maca_eofdelay = 0x00000004; + maca_ccadelay = 0x001a0022; + maca_txccadelay = 0x00000025; + maca_framesync = 0x000000A7; + maca_clk = 0x00000008; +// maca_maskirq = 0; //(maca_irq_cm | maca_irq_acpl | maca_irq_rst | maca_irq_di | maca_irq_crc | maca_irq_flt ); + maca_maskirq = (maca_irq_rst | maca_irq_acpl | maca_irq_cm | maca_irq_flt); + maca_slotoffset = 0x00350000; +} + +void reset_maca(void) +{ + uint32_t tmp; + MACA_WRITE(maca_control, control_seq_nop); + do + { + tmp = MACA_READ(maca_status); + } + while ((tmp & maca_status_cc_mask) == cc_not_completed); + + /* Clear all interrupts. */ + MACA_WRITE(maca_clrirq, 0xFFFF); +} + +/* + 004030c4 : + 4030c4: 4806 ldr r0, [pc, #24] (4030e0 ) // r0 gets base 0x80009a00 + 4030c6: 6881 ldr r1, [r0, #8] // r1 gets *(0x80009a08) + 4030c8: 4806 ldr r0, [pc, #24] (4030e4 ) // r0 gets 0x0000f7df + 4030ca: 4308 orrs r0, r1 // or them, r0 has it + 4030cc: 4904 ldr r1, [pc, #16] (4030e0 ) // r1 gets base 0x80009a00 + 4030ce: 6088 str r0, [r1, #8] // put r0 into 0x80009a08 + 4030d0: 0008 lsls r0, r1, #0 // r0 gets r1, r0 is the base now + 4030d2: 4905 ldr r1, [pc, #20] (4030e8 ) // r1 gets 0x00ffffff + 4030d4: 60c1 str r1, [r0, #12] // put 0x00ffffff into base+12 + 4030d6: 0b09 lsrs r1, r1, #12 // r1 = 0x00ffffff >> 12 + 4030d8: 6101 str r1, [r0, #16] // put r1 base+16 + 4030da: 2110 movs r1, #16 // r1 gets 16 + 4030dc: 6001 str r1, [r0, #0] // put r1 in the base + 4030de: 4770 bx lr // return + 4030e0: 80009a00 .word 0x80009a00 + 4030e4: 0000f7df .word 0x0000f7df + 4030e8: 00ffffff .word 0x00ffffff +*/ + +/* tested and is good */ +#define RF_BASE 0x80009a000 +void flyback_init(void) { + uint32_t val8, or; + + val8 = *(volatile uint32_t *)(RF_BASE+8); + or = val8 | 0x0000f7df; + *(volatile uint32_t *)(RF_BASE+8) = or; + *(volatile uint32_t *)(RF_BASE+12) = 0x00ffffff; + *(volatile uint32_t *)(RF_BASE+16) = (((uint32_t)0x00ffffff)>>12); + *(volatile uint32_t *)(RF_BASE) = 16; + /* good luck and godspeed */ +} + +#define MAX_SEQ1 2 +const uint32_t addr_seq1[MAX_SEQ1] = { + 0x80003048, + 0x8000304c, +}; + +const uint32_t data_seq1[MAX_SEQ1] = { + 0x00000f78, + 0x00607707, +}; + + +#define MAX_SEQ2 2 +const uint32_t addr_seq2[MAX_SEQ2] = { + 0x8000a050, + 0x8000a054, +}; + +const uint32_t data_seq2[MAX_SEQ2] = { + 0x0000047b, + 0x0000007b, +}; + +#define MAX_CAL3_SEQ1 3 +const uint32_t addr_cal3_seq1[MAX_CAL3_SEQ1] = { 0x80009400,0x80009a04,0x80009a00, }; +const uint32_t data_cal3_seq1[MAX_CAL3_SEQ1] = {0x00020017,0x8185a0a4,0x8c900025, }; + +#define MAX_CAL3_SEQ2 2 +const uint32_t addr_cal3_seq2[MAX_CAL3_SEQ2] = { 0x80009a00,0x80009a00,}; +const uint32_t data_cal3_seq2[MAX_CAL3_SEQ2] = { 0x8c900021,0x8c900027,}; + +#define MAX_CAL3_SEQ3 1 +const uint32_t addr_cal3_seq3[MAX_CAL3_SEQ3] = { 0x80009a00 }; +const uint32_t data_cal3_seq3[MAX_CAL3_SEQ3] = { 0x8c900000 }; + +#define MAX_CAL5 4 +const uint32_t addr_cal5[MAX_CAL5] = { + 0x80009400, + 0x8000a050, + 0x8000a054, + 0x80003048, +}; +const uint32_t data_cal5[MAX_CAL5] = { + 0x00000017, + 0x00000000, + 0x00000000, + 0x00000f00, +}; + +#define MAX_DATA 43 +const uint32_t addr_reg_rep[MAX_DATA] = { 0x80004118,0x80009204,0x80009208,0x8000920c,0x80009210,0x80009300,0x80009304,0x80009308,0x8000930c,0x80009310,0x80009314,0x80009318,0x80009380,0x80009384,0x80009388,0x8000938c,0x80009390,0x80009394,0x8000a008,0x8000a018,0x8000a01c,0x80009424,0x80009434,0x80009438,0x8000943c,0x80009440,0x80009444,0x80009448,0x8000944c,0x80009450,0x80009460,0x80009464,0x8000947c,0x800094e0,0x800094e4,0x800094e8,0x800094ec,0x800094f0,0x800094f4,0x800094f8,0x80009470,0x8000981c,0x80009828 }; + +const uint32_t data_reg_rep[MAX_DATA] = { 0x00180012,0x00000605,0x00000504,0x00001111,0x0fc40000,0x20046000,0x4005580c,0x40075801,0x4005d801,0x5a45d800,0x4a45d800,0x40044000,0x00106000,0x00083806,0x00093807,0x0009b804,0x000db800,0x00093802,0x00000015,0x00000002,0x0000000f,0x0000aaa0,0x01002020,0x016800fe,0x8e578248,0x000000dd,0x00000946,0x0000035a,0x00100010,0x00000515,0x00397feb,0x00180358,0x00000455,0x00000001,0x00020003,0x00040014,0x00240034,0x00440144,0x02440344,0x04440544,0x0ee7fc00,0x00000082,0x0000002a }; + + +/* has been tested and it good */ +void vreg_init(void) { + volatile uint32_t i; + *(volatile uint32_t *)(0x80003000) = 0x00000018; /* set default state */ + *(volatile uint32_t *)(0x80003048) = 0x00000f04; /* bypass the buck */ + for(i=0; i<0x161a8; i++) { continue; } /* wait for the bypass to take */ +// while((((*(volatile uint32_t *)(0x80003018))>>17) & 1) !=1) { continue; } /* wait for the bypass to take */ + *(volatile uint32_t *)(0x80003048) = 0x00000ff8; /* start the regulators */ +} + + +/* radio_init has been tested to be good */ +void radio_init(void) { + uint32_t i; + /* sequence 1 */ + for(i=0; i>18) | PAVAL[power]; + reg(ADDR_POW3) = AIMVAL[power]; +} + +const uint8_t VCODivI[16] = { + 0x2f, + 0x2f, + 0x2f, + 0x2f, + 0x2f, + 0x2f, + 0x2f, + 0x2f, + 0x30, + 0x30, + 0x30, + 0x2f, + 0x30, + 0x30, + 0x30, + 0x30, +}; + +const uint32_t VCODivF[16] = { + 0x00355555, + 0x006aaaaa, + 0x00a00000, + 0x00d55555, + 0x010aaaaa, + 0x01400000, + 0x01755555, + 0x01aaaaaa, + 0x01e00000, + 0x00155555, + 0x004aaaaa, + 0x00800000, + 0x00b55555, + 0x00eaaaaa, + 0x01200000, + 0x01555555, +}; + +const uint8_t ctov_4c[16] = { + 0x0b, + 0x0b, + 0x0b, + 0x0a, + 0x0d, + 0x0d, + 0x0c, + 0x0c, + 0x0f, + 0x0e, + 0x0e, + 0x0e, + 0x11, + 0x10, + 0x10, + 0x0f, +}; + +/* tested good */ +#define ADDR_CHAN1 0x80009800 +#define ADDR_CHAN2 ADDR_CHAN1+12 +#define ADDR_CHAN3 ADDR_CHAN1+16 +#define ADDR_CHAN4 ADDR_CHAN1+48 +void set_channel(uint8_t chan) { + volatile uint32_t tmp; + + tmp = reg(ADDR_CHAN1); + tmp = tmp & 0xbfffffff; + reg(ADDR_CHAN1) = tmp; + + reg(ADDR_CHAN2) = VCODivI[chan]; + reg(ADDR_CHAN3) = VCODivF[chan]; + + tmp = reg(ADDR_CHAN4); + tmp = tmp | 2; + reg(ADDR_CHAN4) = tmp; + + tmp = reg(ADDR_CHAN4); + tmp = tmp | 4; + reg(ADDR_CHAN4) = tmp; + + tmp = tmp & 0xffffe0ff; + tmp = tmp | (((ctov_4c[chan])<<8)&0x1F00); + reg(ADDR_CHAN4) = tmp; + /* duh! */ +} + +/* + * Do the ABORT-Wait-NOP-Wait sequence in order to prevent MACA malfunctioning. + * This seqeunce is synchronous and no interrupts should be triggered when it is done. + */ +void ResumeMACASync(void) +{ + uint32_t clk, TsmRxSteps, LastWarmupStep, LastWarmupData, LastWarmdownStep, LastWarmdownData; +// bool_t tmpIsrStatus; + volatile uint32_t i; + +// ITC_DisableInterrupt(gMacaInt_c); +// AppInterrupts_ProtectFromMACAIrq(tmpIsrStatus); <- Original from MAC code, but not sure how is it implemented + + /* Manual TSM modem shutdown */ + + /* read TSM_RX_STEPS */ + TsmRxSteps = (*((volatile uint32_t *)(0x80009204))); + + /* isolate the RX_WU_STEPS */ + /* shift left to align with 32-bit addressing */ + LastWarmupStep = (TsmRxSteps & 0x1f) << 2; + /* Read "current" TSM step and save this value for later */ + LastWarmupData = (*((volatile uint32_t *)(0x80009300 + LastWarmupStep))); + + /* isolate the RX_WD_STEPS */ + /* right-shift bits down to bit 0 position */ + /* left-shift to align with 32-bit addressing */ + LastWarmdownStep = ((TsmRxSteps & 0x1f00) >> 8) << 2; + /* write "last warmdown data" to current TSM step to shutdown rx */ + LastWarmdownData = (*((volatile uint32_t *)(0x80009300 + LastWarmdownStep))); + (*((volatile uint32_t *)(0x80009300 + LastWarmupStep))) = LastWarmdownData; + + /* Abort */ + MACA_WRITE(maca_control, 1); + + /* Wait ~8us */ + for (clk = maca_clk, i = 0; maca_clk - clk < 3 && i < 300; i++) + ; + + /* NOP */ + MACA_WRITE(maca_control, 0); + + /* Wait ~8us */ + for (clk = maca_clk, i = 0; maca_clk - clk < 3 && i < 300; i++) + ; + + + /* restore original "last warmup step" data to TSM (VERY IMPORTANT!!!) */ + (*((volatile uint32_t *)(0x80009300 + LastWarmupStep))) = LastWarmupData; + + + + /* Clear all MACA interrupts - we should have gotten the ABORT IRQ */ + MACA_WRITE(maca_clrirq, 0xFFFF); + +// AppInterrupts_UnprotectFromMACAIrq(tmpIsrStatus); <- Original from MAC code, but not sure how is it implemented +// ITC_EnableInterrupt(gMacaInt_c); +} diff --git a/tests/blink-blue.c b/tests/blink-blue.c index 095fd9cd7..dda1750bf 100644 --- a/tests/blink-blue.c +++ b/tests/blink-blue.c @@ -6,6 +6,7 @@ #include "embedded_types.h" +__attribute__ ((section ("startup"))) void main(void) { *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000400; diff --git a/tests/blink-green.c b/tests/blink-green.c index ededc94e7..2a7aa7add 100644 --- a/tests/blink-green.c +++ b/tests/blink-green.c @@ -6,6 +6,7 @@ #include "embedded_types.h" +__attribute__ ((section ("startup"))) void main(void) { *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000200; diff --git a/tests/blink-red.c b/tests/blink-red.c index 794d82652..0780033e0 100644 --- a/tests/blink-red.c +++ b/tests/blink-red.c @@ -6,8 +6,7 @@ #include "embedded_types.h" -void main(void) { - +__attribute__ ((section ("startup"))) void main(void) { *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000100; volatile uint32_t i; diff --git a/tests/blink-white.c b/tests/blink-white.c index 0376d3f7d..87a7f6720 100644 --- a/tests/blink-white.c +++ b/tests/blink-white.c @@ -6,6 +6,7 @@ #include "embedded_types.h" +__attribute__ ((section ("startup"))) void main(void) { *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000700; diff --git a/tests/rftest-rx.c b/tests/rftest-rx.c new file mode 100644 index 000000000..0e16f7929 --- /dev/null +++ b/tests/rftest-rx.c @@ -0,0 +1,341 @@ +#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ + +#define BASE_UART1 0x80005000 +#define UART1_CON 0x80005000 +#define UART1_STAT 0x80005004 +#define UART1_DATA 0x80005008 +#define UR1CON 0x8000500c +#define UT1CON 0x80005010 +#define UART1_CTS 0x80005014 +#define UART1_BR 0x80005018 + +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 + +#include "maca.h" +#include "embedded_types.h" + +#define reg(x) (*(volatile uint32_t *)(x)) + +#define DELAY 400000 +#define DATA 0x00401000; + +#define NL "\033[K\r\n" + +void putc(uint8_t c); +void puts(uint8_t *s); +void put_hex(uint8_t x); +void put_hex16(uint16_t x); +void put_hex32(uint32_t x); + +const uint8_t hex[16]={'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + +void magic(void) { +#define X 0x80009a000 +#define Y 0x80009a008 +#define VAL 0x0000f7df + volatile uint32_t x,y; + x = reg(X); /* get X */ + x &= 0xfffeffff; /* clear bit 16 */ + reg(X) = x; /* put it back */ + y = reg(Y); /* get Y */ + y |= VAL; /* or with the VAL */ + x = reg(X); /* get X again */ + x |= 16; /* or with 16 */ + reg(X) = x; /* put X back */ + reg(Y) = y; /* put Y back */ +} + +uint32_t ackBox[10]; + +#define MAX_PAYLOAD 128 +volatile uint8_t data[MAX_PAYLOAD]; +/* maca_rxlen is very important */ +#define command_xcvr_rx() \ + do { \ + maca_txlen = ((0xff)<<16); \ + maca_dmatx = (uint32_t)&ackBox; \ + maca_dmarx = data; \ + maca_tmren = (maca_cpl_clk | maca_soft_clk); \ + maca_control = (control_prm | control_asap | control_seq_rx); \ + }while(FALSE) + + +void dump_regs(uint32_t base, uint32_t len) { + volatile uint32_t i; + + puts("base +0 +4 +8 +c +10 +14 +18 +1c \n\r"); + for (i = 0; i < len; i ++) { + if ((i & 7) == 0) { + put_hex16(4 * i); + } + puts(" "); + put_hex32(reg(base+(4*i))); + if ((i & 7) == 7) + puts(NL); + } + puts(NL); +} + +volatile uint8_t led; + +#define led_on() do { led = 1; reg(GPIO_DATA0) = 0x00000200; } while(0); +#define led_off() do { led = 0; reg(GPIO_DATA0) = 0x00000000; } while(0); + +void toggle_led(void) { + if(0 == led) { + led_on(); + led = 1; + + } else { + led_off(); + } +} + +__attribute__ ((section ("startup"))) +void main(void) { + uint8_t c; + volatile uint32_t i; + uint32_t tmp; + uint16_t status; + + *(volatile uint32_t *)GPIO_PAD_DIR0 = 0x00000200; + led_on(); + + /* Restore UART regs. to default */ + /* in case there is still bootloader state leftover */ + + reg(UART1_CON) = 0x0000c800; /* mask interrupts, 16 bit sample --- helps explain the baud rate */ + + /* INC = 767; MOD = 9999 works: 115200 @ 24 MHz 16 bit sample */ + #define INC 767 + #define MOD 9999 + reg(UART1_BR) = INC<<16 | MOD; + + /* see Section 11.5.1.2 Alternate Modes */ + /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ + /* From the datasheet: "The peripheral function will control operation of the pad IF */ + /* THE PERIPHERAL IS ENABLED. */ + reg(UART1_CON) = 0x00000003; /* enable receive and transmit */ + reg(GPIO_FUNC_SEL0) = ( (0x01 << (14*2)) | (0x01 << (15*2)) ); /* set GPIO15-14 to UART (UART1 TX and RX)*/ + + reset_maca(); + radio_init(); + flyback_init(); + vreg_init(); + init_phy(); + + set_power(0x0f); /* 0dbm */ + set_channel(0); /* channel 11 */ + + reg(MACA_CONTROL) = SMAC_MACA_CNTL_INIT_STATE; + for(i=0; i> 8) << 2; */ +/* /\* write "last warmdown data" to current TSM step to shutdown rx *\/ */ +/* LastWarmdownData = (*((volatile uint32_t *)(0x80009300 + LastWarmdownStep))); */ + +/* puts("LastWarmdownData: "); */ +/* put_hex32(LastWarmdownData); */ +/* puts(NL); */ + +/* reg(MACA_CONTROL) = 0x00031a04; /\* receive *\/ */ +/* while (((tmp = reg(MACA_STATUS)) & 15) == 14) */ +/* puts("."); */ +/* puts("complete status is "); put_hex32(tmp); puts(NL); */ +/* puts("1 status is "); put_hex32(reg(MACA_STATUS)); puts(NL); */ +/* puts("2 status is "); put_hex32(reg(MACA_STATUS)); puts(NL); */ +/* puts("3 status is "); put_hex32(reg(MACA_STATUS)); puts(NL); */ + +/* puts(NL); */ +/* for(i=0; i> 4]); + putc(hex[x & 15]); +} + +void put_hex16(uint16_t x) +{ + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} + +void put_hex32(uint32_t x) +{ + put_hex((x >> 24) & 0xFF); + put_hex((x >> 16) & 0xFF); + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} diff --git a/tests/rftest-tx.c b/tests/rftest-tx.c new file mode 100644 index 000000000..fa6309142 --- /dev/null +++ b/tests/rftest-tx.c @@ -0,0 +1,295 @@ +#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ + +#define BASE_UART1 0x80005000 +#define UART1_CON 0x80005000 +#define UART1_STAT 0x80005004 +#define UART1_DATA 0x80005008 +#define UR1CON 0x8000500c +#define UT1CON 0x80005010 +#define UART1_CTS 0x80005014 +#define UART1_BR 0x80005018 + +#define GPIO_PAD_DIR0 0x80000000 +#define GPIO_DATA0 0x80000008 + +#include "maca.h" +#include "embedded_types.h" + +#define reg(x) (*(volatile uint32_t *)(x)) + +#define DELAY 400000 +#define DATA 0x00401000; + +#define NL "\033[K\r\n" + +void putc(uint8_t c); +void puts(uint8_t *s); +void put_hex(uint8_t x); +void put_hex16(uint16_t x); +void put_hex32(uint32_t x); + +const uint8_t hex[16]={'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + +void magic(void) { +#define X 0x80009a000 +#define Y 0x80009a008 +#define VAL 0x0000f7df + volatile uint32_t x,y; + x = reg(X); /* get X */ + x &= 0xfffeffff; /* clear bit 16 */ + reg(X) = x; /* put it back */ + y = reg(Y); /* get Y */ + y |= VAL; /* or with the VAL */ + x = reg(X); /* get X again */ + x |= 16; /* or with 16 */ + reg(X) = x; /* put X back */ + reg(Y) = y; /* put Y back */ +} + +uint32_t ackBox[10]; + +#define command_xcvr_rx() \ + do { \ + maca_txlen = (uint32_t)1<<16; \ + maca_dmatx = (uint32_t)&ackBox; \ + maca_dmarx = DATA; \ + maca_tmren = (maca_cpl_clk | maca_soft_clk); \ + maca_control = (control_prm | control_asap | control_seq_rx); \ + }while(FALSE) + +#define PAYLOAD_LEN 16 /* not including the extra 4 bytes for len+fcs+somethingelse */ +/* maca dmatx needs extra 4 bytes for checksum */ +/* needs + 4 bytes for len(1 byte) + fcs(2 bytes) + somethingelse */ +#define command_xcvr_tx() \ + do { \ + maca_txlen = (uint32_t)(PAYLOAD_LEN+4); \ + maca_dmatx = (uint32_t)DATA; \ + maca_dmarx = (uint32_t)&ackBox; \ + maca_control = (control_prm | control_mode_no_cca | \ + control_asap | control_seq_tx); \ + }while(FALSE) + + + +void dump_regs(uint32_t base, uint32_t len) { + volatile uint32_t i; + + puts("base +0 +4 +8 +c +10 +14 +18 +1c \n\r"); + for (i = 0; i < len; i ++) { + if ((i & 7) == 0) { + put_hex16(4 * i); + } + puts(" "); + put_hex32(reg(base+(4*i))); + if ((i & 7) == 7) + puts(NL); + } + puts(NL); +} + +volatile uint8_t led; + +#define led_on() do { led = 1; reg(GPIO_DATA0) = 0x00000100; } while(0); +#define led_off() do { led = 0; reg(GPIO_DATA0) = 0x00000000; } while(0); + +void toggle_led(void) { + if(0 == led) { + led_on(); + led = 1; + + } else { + led_off(); + } +} + +volatile uint8_t *data; +uint8_t count=0; +void fill_data(void) { + uint8_t i; + for(i=0; i> 4]); + putc(hex[x & 15]); +} + +void put_hex16(uint16_t x) +{ + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} + +void put_hex32(uint32_t x) +{ + put_hex((x >> 24) & 0xFF); + put_hex((x >> 16) & 0xFF); + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} diff --git a/tests/romimg.c b/tests/romimg.c new file mode 100644 index 000000000..51ba68d8b --- /dev/null +++ b/tests/romimg.c @@ -0,0 +1,91 @@ +#define GPIO_FUNC_SEL0 0x80000018 /* GPIO 15 - 0; 2 bit blocks */ + +#define BASE_UART1 0x80005000 +#define UART1_CON 0x80005000 +#define UART1_STAT 0x80005004 +#define UART1_DATA 0x80005008 +#define UR1CON 0x8000500c +#define UT1CON 0x80005010 +#define UART1_CTS 0x80005014 +#define UART1_BR 0x80005018 + +#include "embedded_types.h" + +#define reg(x) (*(volatile uint32_t *)(x)) + +#define DELAY 400000 + +void putc(uint8_t c); +void puts(uint8_t *s); +void put_hex(uint8_t x); +void put_hex16(uint16_t x); +void put_hex32(uint32_t x); + +const uint8_t hex[16]={'0','1','2','3','4','5','6','7', + '8','9','a','b','c','d','e','f'}; + +#define DUMP_BASE 0x00000000 +#define DUMP_LEN 0x00014000 +//#define DUMP_LEN 16 + +__attribute__ ((section ("startup"))) +void main(void) { + volatile uint32_t i; +// volatile uint8_t *data; + volatile uint8_t *data; + + /* Restore UART regs. to default */ + /* in case there is still bootloader state leftover */ + + reg(UART1_CON) = 0x0000c800; /* mask interrupts, 16 bit sample --- helps explain the baud rate */ + + /* INC = 767; MOD = 9999 works: 115200 @ 24 MHz 16 bit sample */ + #define INC 767 + #define MOD 9999 + reg(UART1_BR) = INC<<16 | MOD; + + /* see Section 11.5.1.2 Alternate Modes */ + /* you must enable the peripheral first BEFORE setting the function in GPIO_FUNC_SEL */ + /* From the datasheet: "The peripheral function will control operation of the pad IF */ + /* THE PERIPHERAL IS ENABLED. */ + reg(UART1_CON) = 0x00000003; /* enable receive and transmit */ + reg(GPIO_FUNC_SEL0) = ( (0x01 << (14*2)) | (0x01 << (15*2)) ); /* set GPIO15-14 to UART (UART1 TX and RX)*/ + + for(data=DUMP_BASE; data<(DUMP_BASE+DUMP_LEN); data++) { + putc(*data); + } + + while(1); + +} + +void putc(uint8_t c) { + while(reg(UT1CON)==31); /* wait for there to be room in the buffer */ + reg(UART1_DATA) = c; +} + +void puts(uint8_t *s) { + while(s && *s!=0) { + putc(*s++); + } +} + +void put_hex(uint8_t x) +{ + putc(hex[x >> 4]); + putc(hex[x & 15]); +} + +void put_hex16(uint16_t x) +{ + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} + +void put_hex32(uint32_t x) +{ + put_hex((x >> 24) & 0xFF); + put_hex((x >> 16) & 0xFF); + put_hex((x >> 8) & 0xFF); + put_hex((x) & 0xFF); +} diff --git a/tests/uart1-loopback.c b/tests/uart1-loopback.c index 54e0f7f68..ce516d7ad 100644 --- a/tests/uart1-loopback.c +++ b/tests/uart1-loopback.c @@ -11,6 +11,7 @@ #include "embedded_types.h" +__attribute__ ((section ("startup"))) void main(void) { /* Restore UART regs. to default */ /* in case there is still bootloader state leftover */ @@ -31,6 +32,7 @@ void main(void) { uint8_t c; while(1) { +// *(volatile uint32_t *)UART1_DATA = (uint8_t)'U'; if(*(volatile uint32_t*)UR1CON > 0) { /* Receive buffer isn't empty */ /* read a byte and write it to the transmit buffer */