diff --git a/.gitignore b/.gitignore index cabb2b6..d224ae8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,15 @@ __pycache__ .vscode openocd -*.hex *.code-workspace dist -build mik32_upload.spec +/upload_drivers/jtag_spifi/.pio/build/mik32v2/hal_core +/upload_drivers/jtag_spifi/.pio/build/mik32v2/hal_peripherals +/upload_drivers/jtag_spifi/.pio/build/mik32v2/hal_utilities +*.a +*.o +*.checksum +*.dblite +*.elf +*.map diff --git a/mik32_debug_hal/spifi.py b/mik32_debug_hal/spifi.py index cb4632c..14966b1 100644 --- a/mik32_debug_hal/spifi.py +++ b/mik32_debug_hal/spifi.py @@ -1,3 +1,4 @@ +import datetime from enum import Enum import os import pathlib @@ -209,23 +210,7 @@ def get_segments_list(pages_offsets: List[int], segment_size: int) -> List[int]: return list(segments) -def check_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_spi=False, use_chip_erase=False): - result = 0 - - openocd.halt() - init(openocd) - - # Сбрасываем микросхему в режиме QPI из всех состояний в нормальный SPI режим. - generic_flash.chip_reset_qpi(openocd) - - # Сбрасываем микросхему в режиме SPI из всех состояний в нормальный SPI режим. - generic_flash.chip_reset(openocd) - - JEDEC_ID = send_command(openocd, generic_flash.JEDEC_ID_COMMAND, - Frameform.OPCODE_NOADDR, Fieldform.ALL_SERIAL, 3) - - print(f"JEDEC ID = {JEDEC_ID[0]:02x} {JEDEC_ID[1]:02x} {JEDEC_ID[2]:02x}") - +def dma_config(openocd: OpenOcdTclRpc) -> dma.DMA: dma_instance = dma.DMA(openocd) dma_instance.init() @@ -267,6 +252,28 @@ def check_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_sp dma_instance.channels[1].read_request = dma.ChannelRequest.SPIFI_REQUEST dma_instance.channels[1].read_ack = dma.ChannelAck.DISABLE + return dma_instance + + +def check_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_spi=False, use_chip_erase=False): + result = 0 + + openocd.halt() + init(openocd) + + # Сбрасываем микросхему в режиме QPI из всех состояний в нормальный SPI режим. + generic_flash.chip_reset_qpi(openocd) + + # Сбрасываем микросхему в режиме SPI из всех состояний в нормальный SPI режим. + generic_flash.chip_reset(openocd) + + JEDEC_ID = send_command(openocd, generic_flash.JEDEC_ID_COMMAND, + Frameform.OPCODE_NOADDR, Fieldform.ALL_SERIAL, 3) + + print(f"JEDEC ID = {JEDEC_ID[0]:02x} {JEDEC_ID[1]:02x} {JEDEC_ID[2]:02x}") + + dma_instance = dma_config(openocd) + if (use_quad_spi): print("Using Quad SPI") generic_flash.quad_enable(openocd) @@ -321,46 +328,7 @@ def write_pages(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, use_quad_sp print(f"JEDEC ID = {JEDEC_ID[0]:02x} {JEDEC_ID[1]:02x} {JEDEC_ID[2]:02x}") - dma_instance = dma.DMA(openocd) - dma_instance.init() - - dma_instance.channels[0].write_buffer = 0 - - dma_instance.channels[0].channel = dma.ChannelIndex.CHANNEL_0 - dma_instance.channels[0].priority = dma.ChannelPriority.VERY_HIGH - - dma_instance.channels[0].read_mode = dma.ChannelMode.MEMORY - dma_instance.channels[0].read_increment = dma.ChannelIncrement.ENABLE - dma_instance.channels[0].read_size = dma.ChannelSize.WORD - dma_instance.channels[0].read_burst_size = 2 - dma_instance.channels[0].read_request = dma.ChannelRequest.SPIFI_REQUEST - dma_instance.channels[0].read_ack = dma.ChannelAck.DISABLE - - dma_instance.channels[0].write_mode = dma.ChannelMode.PERIPHERY - dma_instance.channels[0].write_increment = dma.ChannelIncrement.DISABLE - dma_instance.channels[0].write_size = dma.ChannelSize.WORD - dma_instance.channels[0].write_burst_size = 2 - dma_instance.channels[0].write_request = dma.ChannelRequest.SPIFI_REQUEST - dma_instance.channels[0].write_ack = dma.ChannelAck.DISABLE - - dma_instance.channels[1].write_buffer = 0 - - dma_instance.channels[1].channel = dma.ChannelIndex.CHANNEL_1 - dma_instance.channels[1].priority = dma.ChannelPriority.VERY_HIGH - - dma_instance.channels[1].write_mode = dma.ChannelMode.MEMORY - dma_instance.channels[1].write_increment = dma.ChannelIncrement.ENABLE - dma_instance.channels[1].write_size = dma.ChannelSize.WORD - dma_instance.channels[1].write_burst_size = 2 - dma_instance.channels[1].write_request = dma.ChannelRequest.SPIFI_REQUEST - dma_instance.channels[1].write_ack = dma.ChannelAck.DISABLE - - dma_instance.channels[1].read_mode = dma.ChannelMode.PERIPHERY - dma_instance.channels[1].read_increment = dma.ChannelIncrement.DISABLE - dma_instance.channels[1].read_size = dma.ChannelSize.WORD - dma_instance.channels[1].read_burst_size = 2 - dma_instance.channels[1].read_request = dma.ChannelRequest.SPIFI_REQUEST - dma_instance.channels[1].read_ack = dma.ChannelAck.DISABLE + dma_instance = dma_config(openocd) if use_chip_erase: generic_flash.erase(openocd, generic_flash.EraseType.CHIP_ERASE) @@ -440,99 +408,115 @@ def write_pages_by_sectors(pages: Dict[int, List[int]], openocd: OpenOcdTclRpc, openocd.halt() init(openocd) + # openocd.run("rwp") JEDEC_ID = send_command( openocd, 0x9F, Frameform.OPCODE_NOADDR, Fieldform.ALL_SERIAL, 3) print(f"JEDEC_ID {JEDEC_ID[0]:02x} {JEDEC_ID[1]:02x} {JEDEC_ID[2]:02x}") + dma_instance = dma_config(openocd) + sectors_list = get_segments_list(list(pages), 4*1024) openocd.halt() pathname = os.path.dirname(sys.argv[0]) # openocd.run("load_image {%s}" % pathlib.Path(os.path.join(pathname, "firmware.hex"))) - openocd.run("rbp all") openocd.run("load_image {%s}" % pathlib.Path( - "C:\\Users\\user\\Documents\\PlatformIO\\Projects\\SPIFI_JTAG_driver\\.pio\\build\\mik32v2\\firmware.hex")) - openocd.run("bp 0x02002010 1 hw") - openocd.resume(0x02000000) - if wait_halted(openocd) != 0: - return 1 + "C:\\Users\\user\\.platformio\\packages\\tool-mik32-uploader\\upload_drivers\\jtag_spifi\\.pio\\build\\mik32v2\\firmware.hex" + )) + + openocd.run("wp 0x2003000 4 w") + openocd.resume(0x2000000) + wait_halted(openocd) + openocd.halt() # spifi erase - for sector in sectors_list: - print(f"Erase sector {sector}", flush=True) - openocd.write_word(0x02002000, 0b0010 | (sector << 8)) - openocd.resume() - if wait_halted(openocd) != 0: - return 1 - print( - f"Erase sector {sector} result {openocd.read_word(0x02002008)}", flush=True) - - return 1 + # + # for sector in sectors_list: + # print(f"Erase sector {sector}", flush=True) + # openocd.write_word(0x02002000, 0b0010 | (sector << 8)) + # openocd.resume() + # if wait_halted(openocd) != 0: + # return 1 + # print( + # f"Erase sector {sector} result {openocd.read_word(0x02002008)}", flush=True) # spifi erase check - for sector in sectors_list: - # print(f"Erase sector {sector}", flush=True) - # openocd.write_word(0x02002000, 0b0010 | sector) - # openocd.resume() - # if wait_halted(openocd) != 0: - # return 1 - # print(f"Erase sector {sector} result {openocd.read_word(0x02002008)}", flush=True) + # + # for sector in sectors_list: + # # print(f"Erase sector {sector}", flush=True) + # # openocd.write_word(0x02002000, 0b0010 | sector) + # # openocd.resume() + # # if wait_halted(openocd) != 0: + # # return 1 + # # print(f"Erase sector {sector} result {openocd.read_word(0x02002008)}", flush=True) - page_bytes = [0xff] * 256 + # page_bytes = [0xff] * 256 - result = spifi_read_data(openocd, sector, 256, page_bytes) + # result = spifi_read_data(openocd, sector, 256, page_bytes) - if result == 1: - print("Data error") - return result + # if result == 1: + # print("Data error") + # return result for sector in sectors_list: print(f"Program sector {sector}", flush=True) bytes_list: List[int] = [] for page in range(16): - page = pages.get(page * 256 + sector * 4096) + page = pages.get(page * 256 + sector) if page is not None: bytes_list.extend(page) else: bytes_list.extend([0]*256) - extend_value = 1 + sector - bytes_list.extend([(extend_value >> 0) & 0xFF, (extend_value >> 8) - & 0xFF, (extend_value >> 16) & 0xFF, (extend_value >> 24) & 0xFF]) + # extend_value = 1 + sector + # bytes_list.extend([(extend_value >> 0) & 0xFF, (extend_value >> 8) + # & 0xFF, (extend_value >> 16) & 0xFF, (extend_value >> 24) & 0xFF]) # print(bytes_list) - while (openocd.read_word(0x0200200c) != 1): - openocd.resume() - openocd.halt() + openocd.write_memory(0x02002000, 8, bytes_list) + openocd.run(f"set_reg {{t6 {sector}}}") + + openocd.resume() + wait_halted(openocd) + # openocd.halt() + print(f"Check page result {openocd.read_memory(0x2003000, 32, 1)}") + + print(f"{datetime.datetime.now().time()} Program sector {sector} complete", flush=True) + + + + # result = generic_flash.read_data(openocd, sector, 4096, bytes_list) + + # for page in range(16): + # page_bytes = pages.get(page * 256 + sector) + # if page_bytes is not None: + # result = generic_flash.read_data( + # openocd, page * 256 + sector, 256, page_bytes, dma=dma_instance) + + # if result == 1: + # print("Data error") + # return result - openocd.write_memory(0x02001000, 8, bytes_list) - while (openocd.read_word(0x0200200c) != 1): - openocd.resume() - openocd.halt() - time.sleep(0.5) - openocd.halt() - print( - f"Program sector {sector} result {openocd.read_word(0x02002008)}", flush=True) init_memory(openocd) # check write - pages_offsets = list(pages) - for index, page_offset in enumerate(pages_offsets): - page_bytes = pages[page_offset] + # + # pages_offsets = list(pages) + # for index, page_offset in enumerate(pages_offsets): + # page_bytes = pages[page_offset] - memory_bytes = openocd.read_memory(page_offset + 0x80000000, 8, 256) - print(page_offset, memory_bytes) + # memory_bytes = openocd.read_memory(page_offset + 0x80000000, 8, 256) + # print(page_offset, memory_bytes) - for i, byte in enumerate(memory_bytes): - if byte != page_bytes[i]: - print("Data error!") - openocd.run("rbp 0x02002010") - return result + # for i, byte in enumerate(memory_bytes): + # if byte != page_bytes[i]: + # print("Data error!") + # openocd.run("rbp 0x02002010") + # return result - openocd.run("rbp 0x02002010") if result == 0: # Прошивка страниц флеш памяти по SPIFI была завершена print("Flashing of flash memory pages via SPIFI has been completed", flush=True) diff --git a/mik32_upload.py b/mik32_upload.py index bde35eb..c2cccd0 100644 --- a/mik32_upload.py +++ b/mik32_upload.py @@ -263,7 +263,7 @@ def upload_file( gpio_init(openocd, mik_version) start_time = time.perf_counter() - result |= spifi.write_pages( + result |= spifi.write_pages_by_sectors( pages.pages_spifi, openocd, use_quad_spi=use_quad_spi) write_time = time.perf_counter() - start_time diff --git a/upload_drivers/jtag_spifi/.gitignore b/upload_drivers/jtag_spifi/.gitignore new file mode 100644 index 0000000..722d5e7 --- /dev/null +++ b/upload_drivers/jtag_spifi/.gitignore @@ -0,0 +1 @@ +.vscode diff --git a/upload_drivers/jtag_spifi/.pio/build/mik32v2/firmware.hex b/upload_drivers/jtag_spifi/.pio/build/mik32v2/firmware.hex new file mode 100644 index 0000000..79d8128 --- /dev/null +++ b/upload_drivers/jtag_spifi/.pio/build/mik32v2/firmware.hex @@ -0,0 +1,238 @@ +:020000040200F8 +:10000000FD62938202400100FD12E39E02FE374131 +:10001000000213010100B7110002938101EBB71533 +:100020000002938505EB37160002130606EBB716A0 +:100030000002938606EB39A083A2050023A0560098 +:1000400091059106E3EAC5FEB7150002938505EB1D +:1000500037160002130606EBB7160002938606EB6E +:1000600039A083A2050023A0560091059106E3EA7A +:10007000C5FEB7150002938505EB3716000213067F +:1000800006EB21A023A005009105E3EDC5FEB70016 +:100090000002E780C00AB7000002E780C00AB7008C +:1000A0000002E780002373005010F5BF828000003B +:1000B0000000000000000000000000000000000040 +:1000C0006F004000197106C20AC40EC612C816CAD3 +:1000D0001ACC1ECE22D026D22AD42ED632D836DA48 +:1000E0003ADC3EDEC2C0C6C2CAC4CEC6D2C8D6CA78 +:1000F000DACCDECEE2D0E6D2EAD4EED6F2D8F6DA28 +:10010000FADCFEDE970000009380E00482909240CB +:100110002241B2414242D2426243F24302549254DB +:100120002255B2554256D2566257F2570648964863 +:100130002649B649464AD64A664BF64B065C965C5B +:10014000265DB65D465ED65E665FF65F096173004A +:10015000203001A03D432A876373C3029377F700E1 +:10016000BDEFADE5937606FF3D8ABA960CC34CC34E +:100170000CC74CC74107E36BD7FE11E28280B30680 +:10018000C3408A069702000096966780A600230760 +:10019000B700A306B7002306B700A305B7002305E1 +:1001A000B700A304B7002304B700A303B7002303D9 +:1001B000B700A302B7002302B700A301B7002301D1 +:1001C000B700A300B7002300B700828093F5F50FB6 +:1001D00093968500D58D93960501D58D61B793963D +:1001E00027009702000096968682E78086FA96801E +:1001F000C1171D8F3E96E374C3F8A5B75D71130652 +:1002000080028145280886C6B137BD47230CF1001E +:100210008947230EF1003ED2E177938707082C0827 +:100220000A85231AF102EF000079B64061618280ED +:10023000757106C74AC1CEDED2DCD6DADAD8DED690 +:1002400022C526C3653F85653715080001478146ED +:100250002146938555D013050540A122371500028C +:10026000130585E5AD291306400281456818DD3583 +:10027000B707070028183EDCEF0090003715000292 +:10028000130585E6A9292818EF00F012371500029A +:100290001305C5E7A921B729000237150002938588 +:1002A0000900130545E92529B737000223A00700F7 +:1002B00013890700056AB71A0002370B0080916B9B +:1002C0002818EF00500FE256E1679387176AFD1771 +:1002D00081C7D84E418B65FFFE852818EF00B01707 +:1002E000814413840900B3069400B3859F0013066C +:1002F0000010281893840410EF003011E39344FF9A +:10030000514693854AE44800EF003019E2575146C0 +:100310004C0048103ECC02CE02D0EF001018280846 +:10032000EF00407AB307FB01944333077401814720 +:1003300010406303D6008D474104E31BE4FE2320F5 +:10034000F900BDBF0111B717080006CE02C402C6EE +:10035000938707406312F502B70705000947D8CF16 +:10036000930700063EC085473EC28A853745080090 +:100370007126F24005618280B727080093870780C5 +:10038000E319F5FEB70705001147D8CF93070030F2 +:100390003EC03745080085473EC28A8513050540A3 +:1003A000C1BF011122CC26CA4AC84EC652C42A84F3 +:1003B00006CE2E89B284368ABA896937BD4701458F +:1003C00063FE27032320040023262401FD575CCC71 +:1003D0002322440193E714002324340113F744003B +:1003E0001CC0A1885C4C054501C713D56701058970 +:1003F00091CC6DD99396A700E3D606FEF2406244F5 +:10040000D2444249B249224A0561828061DDFDB78A +:10041000484D198105898280411122C406C62A846B +:100420002285FD3775DDB240224441018280931759 +:10043000050137150800C183130505401CD5E9BF28 +:10044000411122C406C62A840305040009E5B2400E +:100450002244410182800504D93FFDB75971D6CAB3 +:10046000DAC8DEC6E2C4E6C2EAC086D6A2D4A6D204 +:10047000CAD0CECED2CC6EDEAA872E8D930A0003D0 +:10048000130BA002930BC004130C0002A94C0385AC +:100490000700630705221307500213891700631131 +:1004A000E5080385170063105509038527001389A4 +:1004B000370085446316650B03240D0093074D0038 +:1004C00063550400330480408944030509003E8DD0 +:1004D00005099377F5FD639777010305090093E418 +:1004E00044000509630E051C13070006AA8763561E +:1004F000A700930705FEE207E1871307F00463886E +:10050000E70C6342F70613073004638CE70A13070E +:1005100040046381E70E130720048946638AE70AD3 +:100520003937EA8951A01307D0026306E500138921 +:100530002700814441B70385270013893700894488 +:1005400095BF3304940305092A940305F9FF1304A6 +:1005500004FD930705FD93F7F70FE374F7FE95BFCE +:1005600001442547FDB7130750056385E7081307C6 +:1005700080056383E70813073005E393E7FA832DCB +:100580000D0093094D0013FA24006E85EF0050050D +:100590002A8D93041D0063150A00636A8D00268D61 +:1005A0006E85793D636A8D004E8DCA87CDB5130582 +:1005B0000002B53D268DF1BF130500028D3D050DEE +:1005C000D5B703050D0093094D009535F1BFA14640 +:1005D00013F7440093094D0015C313064004032785 +:1005E0000D006396C702635407023307E04093E4AB +:1005F000040131A8A946E9BFC146D9BF1307400489 +:100600006395E70003270D00F9BF03270D001305CD +:1006100085F89D4719E193077002100893F5F70FCD +:10062000328D8147A5483378D7023A833385050157 +:100630003357D70263E50801131588016185130557 +:1006400005032300A600938D17006366D3000506FB +:10065000639F8D05FD4713F7040101CF13870D023A +:100660001408B30DD7001307D0022380EDFE938D3D +:10067000270093F714001305000299C31305000324 +:100680006E8A898813071A0081E463648A023A8AB1 +:10069000FD1D3307BD0103050700513BE39A0DFE25 +:1006A000E3748AF0130500025933050AD5BFEE87BB +:1006B0009DBF3AC62AC4A53B324722453A8AD9B7DC +:1006C000B650265496540659F649664AD64A464BC1 +:1006D000B64B264C964C064DF25D656182803971B1 +:1006E0002ED24C1006CE32D436D63AD83EDA42DC80 +:1006F00046DE2EC6A533F24021618280B74708004E +:10070000938707402A886303F508B7570800938743 +:1007100007806303F50A37470800630CE50A0545BF +:100720008280331E1F013376DE0139C2C041884307 +:1007300013931800339662001346F6FF9374340047 +:10074000718DB3946400458D88C3630B740205CC2E +:10075000084303AEC500718D331E6E003365C501BD +:1007600008C38842698E884533156500498E90C25A +:10077000850833D51E0155F53244A24441018280DB +:100780002326C801F1B72324C801D9B7B71605003D +:1007900037170500B7170500938646C1130707C131 +:1007A0009387C7C083AE05008148054F8D429143B2 +:1007B00033D51E0105ED8280B716050037170500F9 +:1007C000B7170500938606C21307C7C1938787C171 +:1007D000D1BFB716050037170500B7170500938678 +:1007E00086C0130747C0938707C06DBF331E1F0124 +:1007F0003376DE0119E2850865BF411122C626C4A1 +:1008000035B70547AA876305E50209476300E50692 +:10081000054591EBB7060600DC4A7D771307F73FE5 +:10082000F98FDCCA014582807D1719EB0D45828066 +:100830009306004037A7070013070712B705050006 +:10084000905D7D8E75D2370606005C4A7D77130772 +:10085000F73FF98FD58F41115CCA02C613073006E6 +:10086000B2476359F700014541018280856693864E +:100870000680C9B7B24785073EC6DDB79147630713 +:10088000F50263EAA7008547630AF504894763090F +:10089000F50405458280A147E31DF5FE094709459A +:1008A00001A8FD1781EFC8D20D45828005470D458F +:1008B000B7A7070093870712B7060500905E798EE9 +:1008C0006DD28A05C98D4111CCD202C613073006FC +:1008D000B247635AF7000145410182801147C9BF01 +:1008E00021470145F1B7B24785073EC6D5B7054751 +:1008F000AA876305E50209476302E506054591EB12 +:10090000B70606009C4A7D771307F73FF98F9CCA0C +:10091000014582807D1719EB0D45828093060040CA +:1009200037A7070013070712B7050500905D7D8EF6 +:1009300075D2370706001C4B7D761306F63FF18F04 +:10094000D58F1CCB85471CCF411102C6130730063B +:10095000B2476359F700014541018280856693865D +:1009600006807DBFB24785073EC6DDB711C9854702 +:10097000630DF50205458280FD1791EB0D458280E0 +:100980000946B7A7070093870712B7060500985EC8 +:10099000718F7DD34111C8D602C613073006B24706 +:1009A0006357F7000145410182800546D9BFB24730 +:1009B00085073EC6EDB7011126CAB7040600DC481C +:1009C00006CE22CC4AC84EC652C456C2F19BDCC8E1 +:1009D0009C482A89C845F19B9CC883C7C5012E84C1 +:1009E0008A07DCC883C7D5018A079CC8193D0C4417 +:1009F000AA8A0345440059351848B70705002A8AD2 +:100A000098C358480850D8C3184C98C7CD35AA8900 +:100A10004850A93F834704002A8793F6170089E6C8 +:100A2000D44893E62600D4C893F6270099E6370603 +:100A30000600544A93E6160054CA93F6470099E616 +:100A400037060600144A93E6260014CAA18B99E7DC +:100A5000B70606009C4A93E717009CCAF24062441E +:100A60002320590123224901232439012326E900A7 +:100A7000D244B249224A924A4A854249056182805B +:100A8000011106CE22CC02C402C62147B7070500D9 +:100A900037550800D8C705448D478A85130505805A +:100AA0003EC022C2A139375508009307C0038A858A +:100AB0001305058022C222C43EC08931F24062443F +:100AC00005618280411122C406C62A84553F184020 +:100AD0005C4F93E707015CCF1C441CCB5C4085CB8B +:100AE0001C43B7061000D58F1CC3144C5C48B240A1 +:100AF000D606CE07D58F83460401C206D58F83461E +:100B0000C4012244E206D58F1CCF410182801C43E0 +:100B1000B706F0FFFD16F58FC1BF032305002A8E2F +:100B20000325C30113650502232EA3002324C3005C +:100B30001396260149824D8E232603012322C300EA +:100B4000139605016354060299C20545B1CB0147CE +:100B50006346D700639C08020D4582803386E70018 +:100B6000034606000507230AC300DDB799C2054501 +:100B700005CB8147E3D0D7FE03260E00034546018F +:100B80003306F70085072300A600EDB783270E0084 +:100B9000FD18DC4F93F70702D5DF11656D8D11E16C +:100BA0008280B707070083C7470113F585001D8DB5 +:100BB0003335A00082801C414147D8CF8280E16854 +:100BC0009388086A01488147014781460146B70575 +:100BD0002006A1B7011106CEA30701008947639340 +:100BE000F502B7052035E1681307F1009388086A1C +:100BF00001488147854601460D37F2400345F10023 +:100C000005618280B7052005F9BF011106CE22CC0F +:100C100026CA2E844AC8AA84328936C64D37B247BE +:100C2000E16822869388086A01480147CA86B78529 +:100C3000800226856164D5351304146A7D1411C4BD +:100C400085452685413F058975F9F2406244D244C5 +:100C5000424905618280011106CE22CC26CA2EC6E9 +:100C6000AA84B13F3246E1689388086A0148814707 +:100C700001478146B705802026856164793D1304CC +:100C8000146A7D1411C485452685A937058975F92F +:100C9000F2406244D24405618280B3C7A5008D8BC7 +:100CA000B308C500B1E78D4763F4C70493773500F7 +:100CB0002A87B9EB13F6C8FFB306E6409307000294 +:100CC00063C8D706AE86BA876371C70203A8060059 +:100CD0009107910623AE07FFE3EAC7FE9307F6FFED +:100CE000998FF19B91073E97BE95636617018280AD +:100CF0002A87637E150383C7050005078505A30FB3 +:100D0000F7FEE39AE8FE828083C605000507937725 +:100D10003700A30FD7FE8505D1DF83C60500050781 +:100D200093773700A30FD7FE8505F9FF61B782805F +:100D3000411122C61304000283A3050083A24500CB +:100D400083AF850003AFC50083AE050103AE450147 +:100D500003A3850103A8C501945113074702B307F4 +:100D6000E640232E77FC232057FE2322F7FF23247F +:100D7000E7FF2326D7FF2328C7FF232A67FE232C5C +:100D800007FF232ED7FE93854502E347F4FAAE868C +:100D9000BA876371C70203A806009107910623AEC4 +:100DA00007FFE3EAC7FE9307F6FF998FF19B9107D0 +:100DB0003E97BE956365170132444101828083C727 +:100DC000050005078505A30FF7FEE387E8FE83C747 +:100DD000050005078505A30FF7FEE392E8FEE9BFCE +:100DE000937735002A879DEFB7867F7F9386F6F746 +:100DF000FD5510431107B377D600B697D18FD58F25 +:100E0000E389B7FE8346C7FFB307A7408DCA834671 +:100E1000D7FF9DC20345E7FF3335A0003E95791506 +:100E20008280F9D283470700050793763700F5FBE8 +:100E3000098F1305F7FF82801385D7FF8280138502 +:100E4000C7FF8280000000000000000000000000DA +:100E50000400000003000000535441525420445247 +:100E6000495645520A0000006D737020696E69741E +:100E700020636F6D706C6574650A0000737069663D +:100E80006920726573657420636F6D706C6574653D +:100E90000A000000425546464552344B203D203062 +:100EA00078253038780A00000000000000000000BB +:0400000502000000F5 +:00000001FF diff --git a/upload_drivers/jtag_spifi/include/README b/upload_drivers/jtag_spifi/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/upload_drivers/jtag_spifi/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/upload_drivers/jtag_spifi/lib/README b/upload_drivers/jtag_spifi/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/upload_drivers/jtag_spifi/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/upload_drivers/jtag_spifi/platformio.ini b/upload_drivers/jtag_spifi/platformio.ini new file mode 100644 index 0000000..a8a79a9 --- /dev/null +++ b/upload_drivers/jtag_spifi/platformio.ini @@ -0,0 +1,16 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:mik32v2] +platform = MIK32 +board = mik32v2 +framework = framework-mik32v2-sdk +board_debug.ldscript = ram +build_flags = -ffixed-x31 -D MIK32V2 diff --git a/upload_drivers/jtag_spifi/ram.ld b/upload_drivers/jtag_spifi/ram.ld new file mode 100644 index 0000000..d786280 --- /dev/null +++ b/upload_drivers/jtag_spifi/ram.ld @@ -0,0 +1,19 @@ + +OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv", "elf32-littleriscv") +OUTPUT_ARCH(riscv) + +ENTRY(_start) + + +MEMORY { + ram (RWX): ORIGIN = 0x02000000, LENGTH = 16K +} + +STACK_SIZE = 1024; + +CL_SIZE = 16; + +REGION_ALIAS("REGION_TEXT", ram); +REGION_ALIAS("REGION_RAM", ram); + +INCLUDE sections.lds diff --git a/upload_drivers/jtag_spifi/sections.lds b/upload_drivers/jtag_spifi/sections.lds new file mode 100644 index 0000000..27c2bec --- /dev/null +++ b/upload_drivers/jtag_spifi/sections.lds @@ -0,0 +1,105 @@ + +SECTIONS { + .text ORIGIN(REGION_TEXT) : { + PROVIDE(__TEXT_START__ = .); + *crt0.o(.text .text.*) + *(.text.smallsysteminit) + *(.text.SmallSystemInit) + . = ORIGIN(REGION_TEXT) + 0xC0; + KEEP(*crt0.o(.trap_text)) + + *(.text) + *(.text.*) + *(.rodata) + *(.rodata.*) + . = ALIGN(CL_SIZE); + PROVIDE(__TEXT_END__ = .); + } >REGION_TEXT + + .data : + AT( __TEXT_END__ ) { + PROVIDE(__DATA_START__ = .); + _gp = .; + *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) + *(.sdata .sdata.* .gnu.linkonce.s.*) + *(.data .data.*) + . = ALIGN(CL_SIZE); + PROVIDE(__DATA_END__ = .); + } >REGION_RAM + + __DATA_IMAGE_START__ = LOADADDR(.data); + __DATA_IMAGE_END__ = LOADADDR(.data) + SIZEOF(.data); + + /* thread-local data segment */ + .tdata : { + PROVIDE(_tls_data = .); + PROVIDE(_tdata_begin = .); + *(.tdata .tdata.*) + PROVIDE(_tdata_end = .); + . = ALIGN(CL_SIZE); + } >REGION_RAM + + .tbss : { + PROVIDE(__BSS_START__ = .); + *(.tbss .tbss.*) + . = ALIGN(CL_SIZE); + PROVIDE(_tbss_end = .); + } >REGION_RAM + + /* bss segment */ + .sbss : { + *(.sbss .sbss.* .gnu.linkonce.sb.*) + *(.scommon) + } >REGION_RAM + + .bss : { + *(.bss .bss.*) + *(COMMON) + . = ALIGN(CL_SIZE); + PROVIDE(__BSS_END__ = .); + } >REGION_RAM + + /* Code intended to be copied to REGION_RAM before execution */ + .ram_text : + AT( ALIGN(__DATA_IMAGE_END__, CL_SIZE) ) { + PROVIDE(__RAM_TEXT_START__ = .); + *(.ram_text) + . = ALIGN(CL_SIZE); + PROVIDE(__RAM_TEXT_END__ = .); + } > REGION_RAM + + __RAM_TEXT_IMAGE_START__ = LOADADDR(.ram_text); + __RAM_TEXT_IMAGE_END__ = LOADADDR(.ram_text) + SIZEOF(.ram_text); + ASSERT(__RAM_TEXT_IMAGE_END__ < ORIGIN(REGION_TEXT) + LENGTH(REGION_TEXT), "REGION_TEXT segment overflows") + + ASSERT(__RAM_TEXT_END__ < ORIGIN(REGION_RAM) + LENGTH(REGION_RAM) - STACK_SIZE, "REGION_RAM section overflows") + + _end = .; + PROVIDE(__end = .); + + BUFFER4K_SIZE = 4K; + + .buffer4k ORIGIN(REGION_RAM) + 8K : { + FILL(0); + PROVIDE(__BUFFER4K__END__ = .); + PROVIDE(BUFFER4K = .); + . += BUFFER4K_SIZE; + PROVIDE(BUFFER_STATUS = .); + . += 4; + PROVIDE(__BUFFER4K__END__ = .); + } >REGION_RAM + + /* End of uninitalized data segement */ + + .stack ORIGIN(REGION_RAM) + LENGTH(REGION_RAM) - STACK_SIZE : { + FILL(0); + PROVIDE(__STACK_START__ = .); + . += STACK_SIZE; + PROVIDE(__C_STACK_TOP__ = .); + PROVIDE(__STACK_END__ = .); + } >REGION_RAM + + /DISCARD/ : { + *(.eh_frame .eh_frame.*) + } +} \ No newline at end of file diff --git a/upload_drivers/jtag_spifi/src/main.c b/upload_drivers/jtag_spifi/src/main.c new file mode 100644 index 0000000..2abe2bc --- /dev/null +++ b/upload_drivers/jtag_spifi/src/main.c @@ -0,0 +1,112 @@ +#include "mik32_hal_pcc.h" +#include "mik32_hal_spifi.h" +#include "mik32_hal_spifi_w25.h" + +#include "uart_lib.h" +#include "xprintf.h" + +/** + * @file main.c + * + * @brief Пример демонстрирует чтение и запись значений во внешнюю флеш память Winbond W25 по Standard (Single) SPI + */ + +// extern char __HEAP_START[]; +const int BUFFER4K_SIZE = 4 * 1024; +extern uint8_t *BUFFER4K[]; +extern uint32_t *BUFFER_STATUS[]; + +register uint32_t address asm ("x31"); + +void SystemClock_Config(void); + +void read_flash(SPIFI_HandleTypeDef *spifi, uint32_t address, uint8_t dataLength, uint8_t *dataBytes); + +int main() +{ + // *BUFFER_STATUS = 1; + SystemClock_Config(); + + UART_Init(UART_0, 3333, UART_CONTROL1_TE_M | UART_CONTROL1_M_8BIT_M, 0, 0); + xprintf("START DRIVER\n"); + + SPIFI_HandleTypeDef spifi = { + .Instance = SPIFI_CONFIG, + }; + + HAL_SPIFI_MspInit(&spifi); + xprintf("msp init complete\n"); + + HAL_SPIFI_Reset(&spifi); + xprintf("spifi reset complete\n"); + + xprintf("BUFFER4K = 0x%08x\n", BUFFER4K); + + *BUFFER_STATUS = 0; + + while (1) { + // asm ("wfi"); + + // *BUFFER_STATUS = 1; + + HAL_SPIFI_Reset(&spifi); + HAL_SPIFI_WaitResetClear(&spifi, HAL_SPIFI_TIMEOUT); + + // xprintf("ERASE SECTOR 0x%08x\n", address); + HAL_SPIFI_W25_SectorErase4K(&spifi, address); + + for (uint32_t ad = 0; ad < BUFFER4K_SIZE; ad += 256) + { + // xprintf("Write Page 0x%08x from 0x%08x\n", ad + address, (uint8_t *)((uint32_t)BUFFER4K + ad)); + HAL_SPIFI_W25_PageProgram(&spifi, ad + address, 256, (uint8_t *)((uint32_t)BUFFER4K + ad)); + } + + SPIFI_MemoryCommandTypeDef cmd_mem = { + .OpCode = 0x03, + .FieldForm = SPIFI_CONFIG_CMD_FIELDFORM_ALL_SERIAL, + .FrameForm = SPIFI_CONFIG_CMD_FRAMEFORM_OPCODE_3ADDR, + .InterimData = 0, + .InterimLength = 0, + }; + + SPIFI_MemoryModeConfig_HandleTypeDef spifi_mem = { + .Instance = spifi.Instance, + .Command = cmd_mem, + }; + + HAL_SPIFI_MemoryMode_Init(&spifi_mem); + + int result = 0; + for (uint32_t ad = 0; ad < BUFFER4K_SIZE; ad += 4) + { + if (*(uint32_t*)(BUFFER4K + ad) != *(uint32_t*)(0x80000000 + address)) + { + result = 3; + } + } + + *BUFFER_STATUS = result; + // asm ("wfi"); + } + + while (1) + ; +} + +void SystemClock_Config(void) +{ + PCC_InitTypeDef PCC_OscInit = {0}; + + PCC_OscInit.OscillatorEnable = PCC_OSCILLATORTYPE_ALL; + PCC_OscInit.FreqMon.OscillatorSystem = PCC_OSCILLATORTYPE_OSC32M; + PCC_OscInit.FreqMon.ForceOscSys = PCC_FORCE_OSC_SYS_UNFIXED; + PCC_OscInit.FreqMon.Force32KClk = PCC_FREQ_MONITOR_SOURCE_OSC32K; + PCC_OscInit.AHBDivider = 0; + PCC_OscInit.APBMDivider = 0; + PCC_OscInit.APBPDivider = 0; + PCC_OscInit.HSI32MCalibrationValue = 128; + PCC_OscInit.LSI32KCalibrationValue = 128; + PCC_OscInit.RTCClockSelection = PCC_RTC_CLOCK_SOURCE_AUTO; + PCC_OscInit.RTCClockCPUSelection = PCC_CPU_RTC_CLOCK_SOURCE_OSC32K; + HAL_PCC_Config(&PCC_OscInit); +} diff --git a/upload_drivers/jtag_spifi/test/README b/upload_drivers/jtag_spifi/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/upload_drivers/jtag_spifi/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html