Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.92 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_device.h"
  11.  
  12. #include "descriptors.h"
  13. #include "serial.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. /* USB CDC functions */
  32.  
  33. static int CDC_SetupCmd(const USB_Setup_TypeDef *setup) {
  34.     return USB_STATUS_REQ_UNHANDLED;
  35. }
  36.  
  37. static int UsbDataReceived(USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining) {
  38.     glo_xferred = xferred;
  39.     if ((status == USB_STATUS_OK) && (xferred > 0)) {
  40.         USBD_Read(CDC_EP_DATA_OUT, (void*)usbRxBuffer, CDC_USB_RX_BUF_SIZ, UsbDataReceived);
  41.     }
  42.     return USB_STATUS_OK;
  43. }
  44.  
  45. static void CDC_StateChangeEvent(USBD_State_TypeDef oldState, USBD_State_TypeDef newState) {
  46.     if (newState == USBD_STATE_CONFIGURED) {
  47.         USBD_Read(CDC_EP_DATA_OUT, (void*)usbRxBuffer, CDC_USB_RX_BUF_SIZ, UsbDataReceived);
  48.     }
  49. }
  50.  
  51. /* USB callbacks */
  52.  
  53. static const USBD_Callbacks_TypeDef callbacks = {
  54.     .usbReset        = NULL,
  55.     .usbStateChange  = CDC_StateChangeEvent,
  56.     .setupCmd        = CDC_SetupCmd,
  57.     .isSelfPowered   = NULL,
  58.     .sofInt          = NULL
  59. };
  60.  
  61. static const USBD_Init_TypeDef usbInitStruct = {
  62.     .deviceDescriptor    = &USBDESC_deviceDesc,
  63.     .configDescriptor    = USBDESC_configDesc,
  64.     .stringDescriptors   = USBDESC_strings,
  65.     .numberOfStrings     = sizeof(USBDESC_strings) / sizeof(void*),
  66.     .callbacks           = &callbacks,
  67.     .bufferingMultiplier = USBDESC_bufferingMultiplier,
  68.     .reserved            = 0
  69. };
  70.  
  71. #define BASE_ADDR      0xE000
  72. #define USB_BLOCK_SIZE 32
  73.  
  74. typedef int (*fptr) (void);
  75.  
  76. typedef enum {
  77.     SYS_LED_0,
  78.     SYS_LED_1
  79. } SystemCall;
  80.  
  81. SL_RAMFUNC_DEFINITION_BEGIN
  82. static bool writeFlashPage(uint32_t* dest, uint32_t* src) {
  83.     MSC_Status_TypeDef status;
  84.     CORE_DECLARE_IRQ_STATE;
  85.     CORE_ENTER_ATOMIC();
  86.     MSC->LOCK = MSC_UNLOCK_CODE;
  87.     status = MSC_ErasePage(dest);
  88.     if (status == mscReturnOk) {
  89.         status = MSC_WriteWord(dest, src, FLASH_PAGE_SIZE);
  90.     }
  91.     MSC->LOCK = 0;
  92.     CORE_EXIT_ATOMIC();
  93.     return (status == mscReturnOk);
  94. }
  95. SL_RAMFUNC_DEFINITION_END
  96.  
  97. void readBinary(uint32_t size, uint32_t* addr) {
  98.     glo_xferred = 0;
  99.     memset(mscBuffer, 0, sizeof(mscBuffer));
  100.     int msc_offset = 0;
  101.     while (1) {
  102.         if (glo_xferred > 0) {
  103.             if (strncmp((char*)usbRxBuffer, "end_binary", 10) == 0) return;
  104.  
  105.             // Serial out.
  106.             memset(serialOutBuffer, 0, sizeof(serialOutBuffer));
  107.             for (int i = 0; i < glo_xferred; i++) {
  108.                 serialOutBuffer[i] = usbRxBuffer[i];
  109.                 if (isprint(serialOutBuffer[i]) == 0) {
  110.                     serialOutBuffer[i] = '.';
  111.                 }
  112.             }
  113.             serialOut(serialOutBuffer);
  114.  
  115.             // Msc.
  116.             for (int i = glo_xferred; i < USB_BLOCK_SIZE; i++) usbRxBuffer[i] = 0;
  117.             memcpy(mscBuffer + msc_offset, usbRxBuffer, USB_BLOCK_SIZE);
  118.             msc_offset += 32;
  119.             if (msc_offset == MSC_BUF_SIZ) {
  120.                 writeFlashPage(addr, (uint32_t*)mscBuffer);
  121.                 addr += (FLASH_PAGE_SIZE / 4);
  122.                 msc_offset = 0;
  123.             }
  124.         }
  125.     }
  126. }
  127.  
  128. int executeBinary(fptr f_ptr) {
  129.     return (*f_ptr)();
  130. }
  131.  
  132. void HardFault_Handler(void) {
  133.     /* Get the stack pointer. */
  134.     uint32_t *sp;
  135.     __asm__ volatile ("mrs %0, msp\n" : "=rm" (sp));
  136.     /* Stack contains:
  137.      *   0 - Stacked r0.
  138.      *   1 - Stacked r1.
  139.      *   2 - Stacked r2.
  140.      *   3 - Stacked r3.
  141.      *   4 - Stacked r12.
  142.      *   5 - Stacked lr.
  143.      *   6 - Stacked pc.
  144.      *   7 - Stacked xPSR.
  145.      */
  146.     uint16_t *addr = sp[6];
  147.     uint16_t instr = *addr;
  148.  
  149.     memset(serialOutBuffer, 0, sizeof(serialOutBuffer));
  150.     sprintf(serialOutBuffer, "Hardfault encountered at address %p, instruction %x.\n", addr, instr);
  151.     serialOut(serialOutBuffer);
  152.  
  153.     /* Force CPU into debug mode. */
  154.     __asm__ volatile ("bkpt #1");
  155. }
  156.  
  157. void SVC_Handler(void) {
  158.     /* Get the stack pointer. */
  159.     uint32_t *sp;
  160.     __asm__ volatile ("mrs %0, msp\n" : "=rm" (sp));
  161.     /* Stack contains:
  162.      *   0 - Stacked r0.
  163.      *   1 - Stacked r1.
  164.      *   2 - Stacked r2.
  165.      *   3 - Stacked r3.
  166.      *   4 - Stacked r12.
  167.      *   5 - Stacked lr.
  168.      *   6 - Stacked pc.
  169.      *   7 - Stacked xPSR.
  170.      */
  171.     /* Get SVC number from first byte of instruction before the stacked PC. */
  172.     uint8_t svc_number = ((uint8_t*)(sp[6]))[-2];
  173.  
  174.     messageOut("System call.\n");
  175.  
  176.     switch(svc_number) {
  177.         case SYS_LED_0:
  178.             GPIO_PinModeSet(gpioPortF, 4, gpioModePushPull, 1);
  179.             break;
  180.  
  181.         case SYS_LED_1:
  182.             GPIO_PinModeSet(gpioPortF, 5, gpioModePushPull, 1);
  183.             break;
  184.  
  185.         default:
  186.  
  187.             messageOut("Unrecognized system call.\n");
  188.             break;
  189.     }
  190. }
  191.  
  192. void usbLoop() {
  193.     int counter = 0;
  194.     while (1) {
  195.         if (glo_xferred > 0) {
  196.             counter += 1;
  197.             if (strncmp((char*)usbRxBuffer, "binary", 6) == 0) {
  198.                 char* end;
  199.                 uint32_t size        = strtol((char*)usbRxBuffer + 7, &end, 10);
  200.                 uint32_t page_offset = strtol(end + 1, &end, 10);
  201.                 uint32_t *addr       = (uint32_t*)(BASE_ADDR + FLASH_PAGE_SIZE * page_offset);
  202.  
  203.                 sprintf(serialOutBuffer, "SIZE %lu ADDR %p\n", size, addr);
  204.                 serialOut(serialOutBuffer);
  205.  
  206.                 readBinary(size, addr);
  207.             }
  208.             else {
  209.                 if (strncmp((char*)usbRxBuffer, "execute", 7) == 0) {
  210.                     char* end;
  211.                     uint32_t exe_id = strtol((char*)usbRxBuffer + 8, &end, 10);
  212.                     // sprintf(serialOutBuffer, "%lu\n", exe_id);
  213.                     // serialOut(serialOutBuffer);
  214.                     uint32_t* _reset_ptr = (uint32_t*)(BASE_ADDR + exe_id * FLASH_PAGE_SIZE);
  215.                     fptr f_ptr = (fptr)(*_reset_ptr);
  216.                     executeBinary(f_ptr);
  217.                 } else {
  218.                     sprintf(serialOutBuffer, "%s\n", usbRxBuffer);
  219.                     serialOut(serialOutBuffer);
  220.                 }
  221.             }
  222.             glo_xferred = 0;
  223.         }
  224.     }
  225. }
  226.  
  227.  
  228. int main(void) {
  229.  
  230.     CHIP_Init();
  231.  
  232.     /* Enable dHFXO and high frequency peripherals */
  233.     CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
  234.     CMU_ClockEnable(cmuClock_HFPER, true);
  235.  
  236.     /* Enabled GPIO and USART1 */
  237.     CMU_ClockEnable(cmuClock_GPIO, true);
  238.     CMU_ClockEnable(cmuClock_USART1, true);
  239.  
  240.     /* Set enable and Tx pin high */
  241.     GPIO_PinModeSet(gpioPortA, 9, gpioModePushPull, 1);
  242.     GPIO_PinModeSet(gpioPortF, 2, gpioModePushPull, 1);
  243.  
  244.     /* Set up interface */
  245.     USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
  246.     USART_InitAsync(USART1, &init);
  247.     USART1->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_LOCATION_LOC4;
  248.  
  249.     /* Initialise MSC. */
  250.     MSC_Init();
  251.  
  252.     /* Initialise USB */
  253.     USBD_Init(&usbInitStruct);
  254.  
  255.     uint8_t testProgram[] = {
  256.         /* Address at which to jump. */
  257.         0x04,
  258.         0xe0,
  259.         0x00,
  260.         0x00,
  261.         /* svc. */
  262.         0x00,
  263.         0xdf,
  264.         /* bx lr. */
  265.         0x70,
  266.         0x47
  267.     };
  268.     writeFlashPage(0xe000, testProgram);
  269.  
  270.     /* Main loop */
  271.     usbLoop();
  272. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement