Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.91 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4.  
  5. #include "em_msc.h"
  6. #include "em_cmu.h"
  7. #include "em_usb.h"
  8. #include "em_chip.h"
  9. #include "em_core.h"
  10. #include "em_usart.h"
  11. #include "em_device.h"
  12.  
  13. #include "descriptors.h"
  14.  
  15. /* USB CDC definitions */
  16.  
  17. #define CDC_BULK_EP_SIZE    USB_FS_BULK_EP_MAXSIZE
  18. #define CDC_USB_RX_BUF_SIZ  CDC_BULK_EP_SIZE
  19. #define CDC_USB_TX_BUF_SIZ  32
  20. #define MSC_BUF_SIZ         1024
  21.  
  22. STATIC_UBUF(usbRxBuffer, CDC_USB_RX_BUF_SIZ);
  23. STATIC_UBUF(mscBuffer,   MSC_BUF_SIZ);
  24.  
  25. static volatile int glo_xferred;
  26.  
  27. /* USB CDC function prototypes */
  28.  
  29. static int UsbDataReceived(USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining);
  30.  
  31. /* Debug messages */
  32.  
  33. char serialOutBuffer[127];
  34.  
  35. void serialOut(char *message) {
  36.     for (uint32_t i = 0; i < strlen(message); i++ ) {
  37.         USART_Tx(USART1, message[i]);
  38.         /* Wait until TXC is set to 1 (last character finished sending). */
  39.         while (!(USART1->IF & 0x1));
  40.     }
  41. }
  42.  
  43. /* USB CDC functions */
  44.  
  45. static int CDC_SetupCmd(const USB_Setup_TypeDef *setup) {
  46.     return USB_STATUS_REQ_UNHANDLED;
  47. }
  48.  
  49. static int UsbDataReceived(USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining) {
  50.     glo_xferred = xferred;
  51.     if ((status == USB_STATUS_OK) && (xferred > 0)) {
  52.         USBD_Read(CDC_EP_DATA_OUT, (void*)usbRxBuffer, CDC_USB_RX_BUF_SIZ, UsbDataReceived);
  53.     }
  54.     return USB_STATUS_OK;
  55. }
  56.  
  57. static void CDC_StateChangeEvent(USBD_State_TypeDef oldState, USBD_State_TypeDef newState) {
  58.     if (newState == USBD_STATE_CONFIGURED) {
  59.         USBD_Read(CDC_EP_DATA_OUT, (void*)usbRxBuffer, CDC_USB_RX_BUF_SIZ, UsbDataReceived);
  60.     }
  61. }
  62.  
  63. /* USB callbacks */
  64.  
  65. static const USBD_Callbacks_TypeDef callbacks = {
  66.     .usbReset        = NULL,
  67.     .usbStateChange  = CDC_StateChangeEvent,
  68.     .setupCmd        = CDC_SetupCmd,
  69.     .isSelfPowered   = NULL,
  70.     .sofInt          = NULL
  71. };
  72.  
  73. static const USBD_Init_TypeDef usbInitStruct = {
  74.     .deviceDescriptor    = &USBDESC_deviceDesc,
  75.     .configDescriptor    = USBDESC_configDesc,
  76.     .stringDescriptors   = USBDESC_strings,
  77.     .numberOfStrings     = sizeof(USBDESC_strings) / sizeof(void*),
  78.     .callbacks           = &callbacks,
  79.     .bufferingMultiplier = USBDESC_bufferingMultiplier,
  80.     .reserved            = 0
  81. };
  82.  
  83. #define BASE_ADDR      0xE000
  84. #define USB_BLOCK_SIZE 32
  85.  
  86. typedef int (*fptr) (void);
  87.  
  88. typedef enum {
  89.     SYS_LED_0,
  90.     SYS_LED_1
  91. } SystemCall;
  92.  
  93. SL_RAMFUNC_DEFINITION_BEGIN
  94. static bool writeFlashPage(uint32_t* dest, uint32_t* src) {
  95.     MSC_Status_TypeDef status;
  96.     CORE_DECLARE_IRQ_STATE;
  97.     CORE_ENTER_ATOMIC();
  98.     MSC->LOCK = MSC_UNLOCK_CODE;
  99.     status = MSC_ErasePage(dest);
  100.     if (status == mscReturnOk) {
  101.         status = MSC_WriteWord(dest, src, FLASH_PAGE_SIZE);
  102.     }
  103.     MSC->LOCK = 0;
  104.     CORE_EXIT_ATOMIC();
  105.     return (status == mscReturnOk);
  106. }
  107. SL_RAMFUNC_DEFINITION_END
  108.  
  109. void readBinary(uint32_t size, uint32_t* addr) {
  110.     glo_xferred = 0;
  111.     memset(mscBuffer, 0, sizeof(mscBuffer));
  112.     int msc_offset = 0;
  113.     while (1) {
  114.         if (glo_xferred > 0) {
  115.             if (strncmp((char*)usbRxBuffer, "end_binary", 10) == 0) return;
  116.  
  117.             // Serial out.
  118.             memset(serialOutBuffer, 0, sizeof(serialOutBuffer));
  119.             for (int i = 0; i < glo_xferred; i++) {
  120.                 serialOutBuffer[i] = usbRxBuffer[i];
  121.                 if (isprint(serialOutBuffer[i]) == 0) {
  122.                     serialOutBuffer[i] = '.';
  123.                 }
  124.             }
  125.             serialOut(serialOutBuffer);
  126.  
  127.             // Msc.
  128.             for (int i = glo_xferred; i < USB_BLOCK_SIZE; i++) usbRxBuffer[i] = 0;
  129.             memcpy(mscBuffer + msc_offset, usbRxBuffer, USB_BLOCK_SIZE);
  130.             msc_offset += 32;
  131.             if (msc_offset == MSC_BUF_SIZ) {
  132.                 writeFlashPage(addr, (uint32_t*)mscBuffer);
  133.                 addr += (FLASH_PAGE_SIZE / 4);
  134.                 msc_offset = 0;
  135.             }
  136.         }
  137.     }
  138. }
  139.  
  140. int executeBinary(fptr f_ptr) {
  141.     return (*f_ptr)();
  142. }
  143.  
  144. void HardFault_Handler(void) {
  145.     memset(serialOutBuffer, 0, sizeof(serialOutBuffer));
  146.     sprintf(serialOutBuffer, "Hard fault at address ");
  147.     serialOut(serialOutBuffer);
  148.  
  149.     /* Fetch which of MSP or PSP is being used into r0. */
  150.     __asm__ volatile (
  151.         /* PSP never used currently.
  152.             "TST lr, #4\n"
  153.             "ITE NEQ\n"
  154.             "MRS r0, PSP\n"
  155.         */
  156.         "mrs r0, MSP\n"
  157.     );
  158.  
  159.     /* Fetch program counter of the failed instruction into addr. */
  160.     register int32_t* addr __asm__("r3");
  161.     __asm__ volatile ("ldr r3, [r0, #0x18]\n");
  162.  
  163.     memset(serialOutBuffer, 0, sizeof(serialOutBuffer));
  164.     sprintf(serialOutBuffer, "%p\n", addr);
  165.     serialOut(serialOutBuffer);
  166.  
  167.     /* Force CPU into debug mode. */
  168.     __asm__ volatile ("bkpt #1");
  169. }
  170.  
  171. void SVC_Handler(void) {
  172.     memset(serialOutBuffer, 0, sizeof(serialOutBuffer));
  173.     sprintf(serialOutBuffer, "Supervisor call.\n");
  174.     serialOut(serialOutBuffer);
  175.  
  176.     __asm__ volatile (
  177.         "mrs r0, MSP\n"
  178.     );
  179.  
  180.     register int32_t msp __asm__("r1");
  181.     SystemCall op;
  182.  
  183.  
  184.     switch(op) {
  185.         case SYS_LED_0:
  186.             GPIO_PinModeSet(gpioPortF, 4, gpioModePushPull, 1);
  187.             break;
  188.         case SYS_LED_1:
  189.             GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 1);
  190.             break;
  191.     }
  192. }
  193.  
  194. void usbLoop() {
  195.     int counter = 0;
  196.     while (1) {
  197.         if (glo_xferred > 0) {
  198.             counter += 1;
  199.             if (strncmp((char*)usbRxBuffer, "binary", 6) == 0) {
  200.                 char* end;
  201.                 uint32_t size        = strtol((char*)usbRxBuffer + 7, &end, 10);
  202.                 uint32_t page_offset = strtol(end + 1, &end, 10);
  203.                 uint32_t *addr       = (uint32_t*)(BASE_ADDR + FLASH_PAGE_SIZE * page_offset);
  204.  
  205.                 sprintf(serialOutBuffer, "SIZE %lu ADDR %p\n", size, addr);
  206.                 serialOut(serialOutBuffer);
  207.  
  208.                 readBinary(size, addr);
  209.             }
  210.             else {
  211.                 if (strncmp((char*)usbRxBuffer, "execute", 7) == 0) {
  212.                     char* end;
  213.                     uint32_t exe_id = strtol((char*)usbRxBuffer + 8, &end, 10);
  214.                     // sprintf(serialOutBuffer, "%lu\n", exe_id);
  215.                     // serialOut(serialOutBuffer);
  216.                     uint32_t* _reset_ptr = (uint32_t*)(BASE_ADDR + exe_id * FLASH_PAGE_SIZE);
  217.                     fptr f_ptr = (fptr)(*_reset_ptr);
  218.                     executeBinary(f_ptr);
  219.                 } else {
  220.                     sprintf(serialOutBuffer, "%s\n", usbRxBuffer);
  221.                     serialOut(serialOutBuffer);
  222.                 }
  223.             }
  224.             glo_xferred = 0;
  225.         }
  226.     }
  227. }
  228.  
  229.  
  230. int main(void) {
  231.  
  232.     CHIP_Init();
  233.  
  234.     /* Enable dHFXO and high frequency peripherals */
  235.     CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
  236.     CMU_ClockEnable(cmuClock_HFPER, true);
  237.  
  238.     /* Enabled GPIO and USART1 */
  239.     CMU_ClockEnable(cmuClock_GPIO, true);
  240.     CMU_ClockEnable(cmuClock_USART1, true);
  241.  
  242.     /* Set enable and Tx pin high */
  243.     GPIO_PinModeSet(gpioPortA, 9, gpioModePushPull, 1);
  244.     GPIO_PinModeSet(gpioPortF, 2, gpioModePushPull, 1);
  245.  
  246.     /* Set up interface */
  247.     USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
  248.     USART_InitAsync(USART1, &init);
  249.     USART1->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_LOCATION_LOC4;
  250.  
  251.     /* Initialise MSC. */
  252.     MSC_Init();
  253.  
  254.     /* Initialise USB */
  255.     USBD_Init(&usbInitStruct);
  256.  
  257.     uint8_t test[128];
  258.     test[0] = 0x12;
  259.     test[1] = 0x34;
  260.     test[3] = 0x56;
  261.     test[4] = 0x78;
  262.     writeFlashPage(0xe000, test);
  263.  
  264.     /* Main loop */
  265.     usbLoop();
  266. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement