diff options
| -rw-r--r-- | README | 14 | ||||
| -rw-r--r-- | libmaple/include/libmaple/usb.h | 1 | ||||
| -rw-r--r-- | libmaple/usb/stm32f1/usb.c | 196 | ||||
| -rw-r--r-- | libmaple/usb/stm32f1/usb_cdcacm.c | 1 | ||||
| -rw-r--r-- | libmaple/usb/stm32f1/usb_midi_device.c | 452 | ||||
| -rw-r--r-- | support/ld/extra_libs.inc | 1 | ||||
| -rw-r--r-- | support/ld/stm32/mem/sram_112k_flash_768k/mem-jtag.inc | 5 | ||||
| -rw-r--r-- | support/ld/stm32/mem/sram_112k_flash_768k/mem-ram.inc | 5 | ||||
| -rw-r--r-- | wirish/boards.cpp | 9 | ||||
| -rw-r--r-- | wirish/boards/maple/board.mk | 12 | ||||
| -rw-r--r-- | wirish/stm32f1/boards_setup.cpp | 2 | ||||
| -rw-r--r-- | wirish/syscalls.c | 5 |
12 files changed, 231 insertions, 472 deletions
@@ -7,7 +7,21 @@ |_| by LeafLabs! leaflabs.com +/************************************************************************************ +Cloned directory with experimental modifications to Leaflabs main libmaple code + +Work in progress include: +* usb-midi, currently only for stm32f1xxx targets +* stm32f4 support, i2c is working +* support for Netduino 2 and Netduino plus 2 + +All experimental code needs more cleanup and testing, so it is supplied as is :) + +Magnus Lundin +lundin@mlu.mine.nu + +*************************************************************************************/ The latest version of this repository can be found here: https://github.com/leaflabs/libmaple diff --git a/libmaple/include/libmaple/usb.h b/libmaple/include/libmaple/usb.h index 2be5971..ea24030 100644 --- a/libmaple/include/libmaple/usb.h +++ b/libmaple/include/libmaple/usb.h @@ -151,6 +151,7 @@ typedef struct usblib_dev { void (**ep_int_in)(void); void (**ep_int_out)(void); usb_dev_state state; + usb_dev_state prevState; rcc_clk_id clk_id; } usblib_dev; diff --git a/libmaple/usb/stm32f1/usb.c b/libmaple/usb/stm32f1/usb.c index c20cc71..f694f04 100644 --- a/libmaple/usb/stm32f1/usb.c +++ b/libmaple/usb/stm32f1/usb.c @@ -28,7 +28,7 @@ * @file libmaple/usb/stm32f1/usb.c * @brief USB support. * - * This is a mess. What we need almost amounts to a ground-up rewrite. + * This is a mess. */ #include <libmaple/usb.h> @@ -69,13 +69,14 @@ typedef enum { } RESUME_STATE; struct { - volatile RESUME_STATE eState; - volatile uint8 bESOFcnt; + volatile RESUME_STATE eState; + volatile uint8 bESOFcnt; } ResumeS; static usblib_dev usblib = { .irq_mask = USB_ISR_MSK, .state = USB_UNCONNECTED, + .prevState = USB_UNCONNECTED, .clk_id = RCC_USB, }; usblib_dev *USBLIB = &usblib; @@ -105,147 +106,151 @@ void usb_init_usblib(usblib_dev *dev, } static void usb_suspend(void) { - uint16 cntr; - - /* TODO decide if read/modify/write is really what we want - * (e.g. usb_resume_init() reconfigures CNTR). */ - cntr = USB_BASE->CNTR; - cntr |= USB_CNTR_FSUSP; - USB_BASE->CNTR = cntr; - cntr |= USB_CNTR_LP_MODE; - USB_BASE->CNTR = cntr; - - USBLIB->state = USB_SUSPENDED; + uint16 cntr; + + /* TODO decide if read/modify/write is really what we want + * (e.g. usb_resume_init() reconfigures CNTR). */ + cntr = USB_BASE->CNTR; + cntr |= USB_CNTR_FSUSP; + USB_BASE->CNTR = cntr; + cntr |= USB_CNTR_LP_MODE; + USB_BASE->CNTR = cntr; + + USBLIB->prevState = USBLIB->state; + USBLIB->state = USB_SUSPENDED; } static void usb_resume_init(void) { - uint16 cntr; + uint16 cntr; - cntr = USB_BASE->CNTR; - cntr &= ~USB_CNTR_LP_MODE; - USB_BASE->CNTR = cntr; + cntr = USB_BASE->CNTR; + cntr &= ~USB_CNTR_LP_MODE; + USB_BASE->CNTR = cntr; - /* Enable interrupt lines */ - USB_BASE->CNTR = USB_ISR_MSK; + /* Enable interrupt lines */ + USB_BASE->CNTR = USB_ISR_MSK; } static void usb_resume(RESUME_STATE eResumeSetVal) { - uint16 cntr; + uint16 cntr; - if (eResumeSetVal != RESUME_ESOF) - ResumeS.eState = eResumeSetVal; + if (eResumeSetVal != RESUME_ESOF) { + ResumeS.eState = eResumeSetVal; + } - switch (ResumeS.eState) - { + switch (ResumeS.eState) { case RESUME_EXTERNAL: - usb_resume_init(); - ResumeS.eState = RESUME_OFF; - break; + usb_resume_init(); + ResumeS.eState = RESUME_OFF; + USBLIB->state = USBLIB->prevState; + break; case RESUME_INTERNAL: - usb_resume_init(); - ResumeS.eState = RESUME_START; - break; + usb_resume_init(); + ResumeS.eState = RESUME_START; + break; case RESUME_LATER: - ResumeS.bESOFcnt = 2; - ResumeS.eState = RESUME_WAIT; - break; + ResumeS.bESOFcnt = 2; + ResumeS.eState = RESUME_WAIT; + break; case RESUME_WAIT: - ResumeS.bESOFcnt--; - if (ResumeS.bESOFcnt == 0) - ResumeS.eState = RESUME_START; - break; + ResumeS.bESOFcnt--; + if (ResumeS.bESOFcnt == 0) { + ResumeS.eState = RESUME_START; + } + break; case RESUME_START: - cntr = USB_BASE->CNTR; - cntr |= USB_CNTR_RESUME; - USB_BASE->CNTR = cntr; - ResumeS.eState = RESUME_ON; - ResumeS.bESOFcnt = 10; - break; + cntr = USB_BASE->CNTR; + cntr |= USB_CNTR_RESUME; + USB_BASE->CNTR = cntr; + ResumeS.eState = RESUME_ON; + ResumeS.bESOFcnt = 10; + break; case RESUME_ON: - ResumeS.bESOFcnt--; - if (ResumeS.bESOFcnt == 0) { - cntr = USB_BASE->CNTR; - cntr &= ~USB_CNTR_RESUME; - USB_BASE->CNTR = cntr; - ResumeS.eState = RESUME_OFF; - } - break; + ResumeS.bESOFcnt--; + if (ResumeS.bESOFcnt == 0) { + cntr = USB_BASE->CNTR; + cntr &= ~USB_CNTR_RESUME; + USB_BASE->CNTR = cntr; + USBLIB->state = USBLIB->prevState; + ResumeS.eState = RESUME_OFF; + } + break; case RESUME_OFF: case RESUME_ESOF: default: - ResumeS.eState = RESUME_OFF; - break; + ResumeS.eState = RESUME_OFF; + break; } } #define SUSPEND_ENABLED 1 void __irq_usb_lp_can_rx0(void) { - uint16 istr = USB_BASE->ISTR; + uint16 istr = USB_BASE->ISTR; - /* Use USB_ISR_MSK to only include code for bits we care about. */ + /* Use USB_ISR_MSK to only include code for bits we care about. */ #if (USB_ISR_MSK & USB_ISTR_RESET) - if (istr & USB_ISTR_RESET & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_RESET; - pProperty->Reset(); - } + if (istr & USB_ISTR_RESET & USBLIB->irq_mask) { + USB_BASE->ISTR = ~USB_ISTR_RESET; + pProperty->Reset(); + } #endif #if (USB_ISR_MSK & USB_ISTR_PMAOVR) - if (istr & ISTR_PMAOVR & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_PMAOVR; - } + if (istr & ISTR_PMAOVR & USBLIB->irq_mask) { + USB_BASE->ISTR = ~USB_ISTR_PMAOVR; + } #endif #if (USB_ISR_MSK & USB_ISTR_ERR) - if (istr & USB_ISTR_ERR & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_ERR; - } + if (istr & USB_ISTR_ERR & USBLIB->irq_mask) { + USB_BASE->ISTR = ~USB_ISTR_ERR; + } #endif #if (USB_ISR_MSK & USB_ISTR_WKUP) - if (istr & USB_ISTR_WKUP & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_WKUP; - usb_resume(RESUME_EXTERNAL); - } + if (istr & USB_ISTR_WKUP & USBLIB->irq_mask) { + USB_BASE->ISTR = ~USB_ISTR_WKUP; + usb_resume(RESUME_EXTERNAL); + } #endif #if (USB_ISR_MSK & USB_ISTR_SUSP) - if (istr & USB_ISTR_SUSP & USBLIB->irq_mask) { - /* check if SUSPEND is possible */ - if (SUSPEND_ENABLED) { - usb_suspend(); - } else { - /* if not possible then resume after xx ms */ - usb_resume(RESUME_LATER); + if (istr & USB_ISTR_SUSP & USBLIB->irq_mask) { + /* check if SUSPEND is possible */ + if (SUSPEND_ENABLED) { + usb_suspend(); + } else { + /* if not possible then resume after xx ms */ + usb_resume(RESUME_LATER); + } + /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ + USB_BASE->ISTR = ~USB_ISTR_SUSP; } - /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ - USB_BASE->ISTR = ~USB_ISTR_SUSP; -} #endif #if (USB_ISR_MSK & USB_ISTR_SOF) - if (istr & USB_ISTR_SOF & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_SOF; - } + if (istr & USB_ISTR_SOF & USBLIB->irq_mask) { + USB_BASE->ISTR = ~USB_ISTR_SOF; + } #endif #if (USB_ISR_MSK & USB_ISTR_ESOF) - if (istr & USB_ISTR_ESOF & USBLIB->irq_mask) { - USB_BASE->ISTR = ~USB_ISTR_ESOF; - /* resume handling timing is made with ESOFs */ - usb_resume(RESUME_ESOF); /* request without change of the machine state */ - } + if (istr & USB_ISTR_ESOF & USBLIB->irq_mask) { + USB_BASE->ISTR = ~USB_ISTR_ESOF; + /* resume handling timing is made with ESOFs */ + usb_resume(RESUME_ESOF); /* request without change of the machine state */ + } #endif - /* - * Service the correct transfer interrupt. - */ + /* + * Service the correct transfer interrupt. + */ #if (USB_ISR_MSK & USB_ISTR_CTR) - if (istr & USB_ISTR_CTR & USBLIB->irq_mask) { - dispatch_ctr_lp(); - } + if (istr & USB_ISTR_CTR & USBLIB->irq_mask) { + dispatch_ctr_lp(); + } #endif } @@ -274,8 +279,9 @@ static void dispatch_ctr_lp() { * once we're done serving endpoint zero, but not okay if * there are multiple nonzero endpoint transfers to * handle. */ - if (dispatch_endpt_zero(istr & USB_ISTR_DIR)) + if (dispatch_endpt_zero(istr & USB_ISTR_DIR)) { return; + } } else { dispatch_endpt(ep_id); } diff --git a/libmaple/usb/stm32f1/usb_cdcacm.c b/libmaple/usb/stm32f1/usb_cdcacm.c index dfd8d56..d4d4262 100644 --- a/libmaple/usb/stm32f1/usb_cdcacm.c +++ b/libmaple/usb/stm32f1/usb_cdcacm.c @@ -609,6 +609,7 @@ static void usbReset(void) { n_unread_bytes = 0; n_unsent_bytes = 0; rx_offset = 0; + transmitting = 0; } static RESULT usbDataSetup(uint8 request) { diff --git a/libmaple/usb/stm32f1/usb_midi_device.c b/libmaple/usb/stm32f1/usb_midi_device.c index ed6ca70..c26d86e 100644 --- a/libmaple/usb/stm32f1/usb_midi_device.c +++ b/libmaple/usb/stm32f1/usb_midi_device.c @@ -64,7 +64,7 @@ *****************************************************************************/ #if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \ - defined(BOARD_maple_mini) || defined(BOARD_maple_midi) || defined(BOARD_maple_native)) + defined(BOARD_maple_mini) || defined(BOARD_maple_native)) #warning USB MIDI relies on LeafLabs board-specific configuration.\ You may have problems on non-LeafLabs boards. #endif @@ -129,18 +129,22 @@ static void (*ep_int_out[7])(void) = /* * Globals required by usb_lib/ * - * Mark these weak so they can be overriden to implement other USB - * functionality. + * These will override _weak defines in usb_cdcasm.c + * */ +#if defined(USB_TYPE) && (USB_TYPE==USB_MIDI) + #define NUM_ENDPTS 0x04 -__weak DEVICE Device_Table = { + +DEVICE Device_Table = { .Total_Endpoint = NUM_ENDPTS, .Total_Configuration = 1 }; #define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */ -__weak DEVICE_PROP Device_Property = { + +DEVICE_PROP Device_Property = { .Init = usbInit, .Reset = usbReset, .Process_Status_IN = NOP_Process, @@ -155,7 +159,7 @@ __weak DEVICE_PROP Device_Property = { .MaxPacketSize = MAX_PACKET_SIZE }; -__weak USER_STANDARD_REQUESTS User_Standard_Requests = { +USER_STANDARD_REQUESTS User_Standard_Requests = { .User_GetConfiguration = NOP_Process, .User_SetConfiguration = usbSetConfiguration, .User_GetInterface = NOP_Process, @@ -228,6 +232,75 @@ uint32 usb_midi_tx(const uint32* buf, uint32 packets) { return packets; } +/* + * Theese functions replaces EP double buffering: + * + * usb_midi_tx_buffered(const uint8* buf, uint32 len) + * usb_midi_tx_send_buffer() + * + * TODO: Use the modules EP double buffering instead + * + * */ +uint32 usb_midi_tx_buffered(const uint8* buf, uint32 len) { + if (usb_midi_is_transmitting()) { + uint8 count; + /* Copy to TxBuffer */ + /* Disable USB EP interrupts */ + USB_BASE->CNTR = USB_ISR_MSK&~USB_CNTR_CTRM; + if (len>(USB_MIDI_TX_EPSIZE-tx_offset)) len = USB_MIDI_TX_EPSIZE-tx_offset; + for (count=0;count<len;count++) + { + midiBufferTx[tx_offset+count]=buf[count]; + } + tx_offset += len; + /* Reenable USB EP interrupts */ + USB_BASE->CNTR = USB_ISR_MSK&~USB_CNTR_CTRM; + return len; /* return len */ + } + + /* We can only put USB_MIDI_TX_EPSIZE bytes in the buffer. */ + if (len > USB_MIDI_TX_EPSIZE) { + len = USB_MIDI_TX_EPSIZE; + } + + /* Queue bytes for sending. */ + if (len) { + usb_copy_to_pma(buf, len, USB_MIDI_TX_ADDR); + } + // We still need to wait for the interrupt, even if we're sending + // zero bytes. (Sending zero-size packets is useful for flushing + // host-side buffers.) + usb_set_ep_tx_count(USB_MIDI_TX_ENDP, len); + n_unsent_bytes = len; + transmitting = 1; + usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_VALID); + + return len; +} + +#ifdef USETXBUFFER +uint32 usb_midi_tx_send_buffer() { + if (usb_midi_is_transmitting()) { + return 0; + } + /* Queue bytes for sending. */ + if (tx_offset) { + usb_copy_to_pma((const uint8 *)midiBufferTx, tx_offset, USB_MIDI_TX_ADDR); + } + else return 0; + // We still need to wait for the interrupt, even if we're sending + // zero bytes. (Sending zero-size packets is useful for flushing + // host-side buffers.) + usb_set_ep_tx_count(USB_MIDI_TX_ENDP, tx_offset); + n_unsent_bytes = tx_offset; + tx_offset = 0; + transmitting = 1; + usb_set_ep_tx_stat(USB_MIDI_TX_ENDP, USB_EP_STAT_TX_VALID); + + return n_unsent_bytes; +} +#endif + uint32 usb_midi_data_available(void) { return n_unread_packets; } @@ -286,6 +359,9 @@ uint32 usb_midi_peek(uint32* buf, uint32 packets) { static void midiDataTxCb(void) { n_unsent_packets = 0; transmitting = 0; +#ifdef USETXBUFFER + usb_midi_tx_send_buffer(); +#endif } static void midiDataRxCb(void) { @@ -371,6 +447,7 @@ static void usbReset(void) { n_unsent_packets = 0; rx_offset = 0; tx_offset = 0; + transmitting = 0; } static RESULT usbDataSetup(uint8 request) { @@ -418,365 +495,4 @@ static void usbSetDeviceAddress(void) { USBLIB->state = USB_ADDRESSED; } -/* ------------------------------------------------------------------------------------------ - * - * Minimal Sysex Handler - * - *------------------------------------------------------------------------------------------- - * The idea is to provide enough sysex functionality to id the device, and reset it. - *------------------------------------------------------------------------------------------*/ - - -const uint8 standardIDResponse[]={ - MIDIv1_SYSEX_START, - USYSEX_NON_REAL_TIME, - USYSEX_ALL_CHANNELS, - USYSEX_GENERAL_INFO, - USYSEX_GI_ID_RESPONSE, - LEAFLABS_MMA_VENDOR_1, - LEAFLABS_MMA_VENDOR_2, // extended ID - LEAFLABS_MMA_VENDOR_3, // extended ID - 1, // family #1 - 2, // family #2 - 1, // part #1 - 2, // part #2 - 0, // version 1 - 0, // version 2 - 1, // version 3 - '!', // lgl compatible - MIDIv1_SYSEX_END -}; - -#define STANDARD_ID_RESPONSE_LENGTH (sizeof(standardIDResponse)) - -typedef enum {NOT_IN_SYSEX=0,COULD_BE_MY_SYSEX,YUP_ITS_MY_SYSEX,ITS_NOT_MY_SYSEX} sysexStates; -volatile uint8 sysexBuffer[MAX_SYSEX_LENGTH]; -volatile sysexStates sysexState; -volatile int sysexFinger=0; -volatile uint8 myMidiChannel = DEFAULT_MIDI_CHANNEL; -volatile uint8 myMidiDevice = DEFAULT_MIDI_DEVICE; -volatile uint8 myMidiCable = DEFAULT_MIDI_CABLE; -volatile uint8 myMidiID[] = { LEAFLABS_MMA_VENDOR_1,LEAFLABS_MMA_VENDOR_2,LEAFLABS_MMA_VENDOR_3,0}; - -/* - 0xF0 SysEx - 0x?? LEAFLABS_MMA_VENDOR_1 - 0x?? LEAFLABS_MMA_VENDOR_2 - - 0x?? LEAFLABS_MMA_VENDOR_3 - 0x10 LGL_DEVICE_NUMBER - 0xLE CMD: REBOOT - - 0xf7 EOSysEx - */ -#define STACK_TOP 0x20000800 -#define EXC_RETURN 0xFFFFFFF9 -#define DEFAULT_CPSR 0x61000000 -#define RESET_DELAY 100000 -static void wait_reset(void) { - delay_us(RESET_DELAY); - nvic_sys_reset(); -} - -/* -----------------------------------------------------------------------------dealWithItQuickly() - * Note: at this point we have established that the sysex belongs to us. - * So we need to respond to any generic requests like information requests. - * We also need to handle requests which are meant for us. At the moment this is just the - * reset request. - * - */ -void dealWithItQuickly(){ - switch (sysexBuffer[1]) { - case USYSEX_NON_REAL_TIME: - switch (sysexBuffer[3]) { - case USYSEX_GENERAL_INFO: - if (sysexBuffer[4]==USYSEX_GI_ID_REQUEST) { - //usb_midi_tx((uint32 *) standardIDResponse, STANDARD_ID_RESPONSE_LENGTH); - usb_midi_send_sysex(standardIDResponse,17); - } - } - case USYSEX_REAL_TIME: - break; - case LEAFLABS_MMA_VENDOR_1: - if (sysexBuffer[5]==LGL_RESET_CMD) { - uintptr_t target = (uintptr_t)wait_reset | 0x1; - asm volatile("mov r0, %[stack_top] \n\t" // Reset stack - "mov sp, r0 \n\t" - "mov r0, #1 \n\t" - "mov r1, %[target_addr] \n\t" - "mov r2, %[cpsr] \n\t" - "push {r2} \n\t" // Fake xPSR - "push {r1} \n\t" // PC target addr - "push {r0} \n\t" // Fake LR - "push {r0} \n\t" // Fake R12 - "push {r0} \n\t" // Fake R3 - "push {r0} \n\t" // Fake R2 - "push {r0} \n\t" // Fake R1 - "push {r0} \n\t" // Fake R0 - "mov lr, %[exc_return] \n\t" - "bx lr" - : - : [stack_top] "r" (STACK_TOP), - [target_addr] "r" (target), - [exc_return] "r" (EXC_RETURN), - [cpsr] "r" (DEFAULT_CPSR) - : "r0", "r1", "r2"); - /* Can't happen. */ - ASSERT_FAULT(0); - - } - - default: - break; - } - ;//turn the led on? -} - -/* ----------------------------------------------------------------------usb_minimal_sysex_handler() - * The idea here is to identify which Sysex's belong to us and deal with them. - */ -void usb_minimal_sysex_handler(uint32 *midiBufferRx, uint32 *rx_offset, uint32 *n_unread_packets) { - USB_MIDI_Event_Packet * midiPackets = (USB_MIDI_Event_Packet *) (midiBufferRx+(*rx_offset)); - uint8 nPackets=((*n_unread_packets)-(*rx_offset)); - uint32 cPacket; - uint8 soPackets=0; - /********************************* ACHTUNG! ignores usbmidi cable ********************************/ - USB_MIDI_Event_Packet e; - for (cPacket=0;cPacket<nPackets;cPacket++){ - e=midiPackets[cPacket]; - if (!CIN_IS_SYSEX(e.packet.cin)) { - continue; - } // else { - if (!soPackets) { - soPackets=cPacket; - } - if ((sysexState==YUP_ITS_MY_SYSEX) && ((sysexFinger+3)>=MAX_SYSEX_LENGTH)){ - sysexState=ITS_NOT_MY_SYSEX; //eisenhower policy. Even if its mine I cant deal with it. - } - switch (e.packet.cin) { - case CIN_SYSEX: - switch (sysexState) { - case NOT_IN_SYSEX : // new sysex. - sysexFinger=0; - if (e.packet.midi0 == MIDIv1_SYSEX_START) { - if (e.packet.midi1==USYSEX_REAL_TIME - ||e.packet.midi1==USYSEX_NON_REAL_TIME) { - if ((e.packet.midi2==myMidiChannel) - ||(e.packet.midi2==USYSEX_ALL_CHANNELS) - ) { - sysexState=YUP_ITS_MY_SYSEX; - sysexBuffer[sysexFinger++]=MIDIv1_SYSEX_START; - sysexBuffer[sysexFinger++]=e.packet.midi1; - sysexBuffer[sysexFinger++]=e.packet.midi2; - break; - } - } else if ((e.packet.midi1==myMidiID[0]) - && (e.packet.midi2==myMidiID[1]) - ){ - sysexState=COULD_BE_MY_SYSEX; - sysexBuffer[sysexFinger++]=MIDIv1_SYSEX_START; - sysexBuffer[sysexFinger++]=e.packet.midi1; - sysexBuffer[sysexFinger++]=e.packet.midi2; - break; - } - } - break; - - case COULD_BE_MY_SYSEX: - if (e.packet.midi0==myMidiID[2]) { - sysexState=YUP_ITS_MY_SYSEX; - sysexBuffer[sysexFinger++]=e.packet.midi0; - sysexBuffer[sysexFinger++]=e.packet.midi1; - sysexBuffer[sysexFinger++]=e.packet.midi2; - } else { - sysexState=ITS_NOT_MY_SYSEX; - sysexFinger=0; - } - break; - default: - break; - - } - - break; - case CIN_SYSEX_ENDS_IN_1: - case CIN_SYSEX_ENDS_IN_2: - case CIN_SYSEX_ENDS_IN_3: - sysexBuffer[sysexFinger++]=e.packet.midi0; - sysexBuffer[sysexFinger++]=e.packet.midi1; - sysexBuffer[sysexFinger++]=e.packet.midi2; - if (sysexState==YUP_ITS_MY_SYSEX) { - if(cPacket>=(*n_unread_packets)){ - *n_unread_packets = soPackets; - *rx_offset = soPackets; - } else { - uint32 s; - uint32 d; - for (s = cPacket, d=soPackets; - ((*n_unread_packets) && (s <= USB_MIDI_RX_EPSIZE/4)); - d++,s++ - ) { - midiPackets[d]=midiPackets[s]; - (*n_unread_packets)--; - (*rx_offset)++; - - } - // we need to reset the for loop variables to re process remaining data. - nPackets=((*n_unread_packets)-(*rx_offset)); - cPacket=(*rx_offset); - } - dealWithItQuickly(); - - } - sysexFinger=0; - sysexState=NOT_IN_SYSEX; - - break; - default: - return; - } - //} - - - - } - // its our sysex and we will cry if we want to - return; -} -/* ---------------------------------------------------------------------------usb_midi_send_sysex() - * This is currently more expensive memory wise than I would like and will only send sysex - * the sysexex can be complete or just the body. - * all characters between start and end of the sysex will be stripped of the hi bit. - */ - -#define SYSEX_OUT_BUFFER_LENGTH (MAX_SYSEX_LENGTH*7/3)+4 -static volatile uint8 sysexOutBuffer[SYSEX_OUT_BUFFER_LENGTH]; - -uint32 usb_midi_send_sysex(uint8 *sysex, uint32 bytes2send) { - int j=1; - uint32 i=0; - uint32 buffered=0; - - if (bytes2send && ( sysex[bytes2send-1] != MIDIv1_SYSEX_END ) ) { - bytes2send++; // make room for end of sysex - } - if (bytes2send > (SYSEX_OUT_BUFFER_LENGTH - 4)) { - return 0; // if its to big then fahgetaboutit - } - while (bytes2send > 3 /*&& buffered<=SYSEX_OUT_BUFFER_LENGTH */) { - sysexOutBuffer[buffered++]=CIN_SYSEX; - if (buffered==1) { - sysexOutBuffer[buffered++]=MIDIv1_SYSEX_START; - if (sysex[i]==MIDIv1_SYSEX_START){ - i++; // note: output count will be off by 1 for incomplete sysex messages - } - } else { - sysexOutBuffer[buffered++]=sysex[i++] & 0x7f; - } - sysexOutBuffer[buffered++]=sysex[i++] & 0x7f; - sysexOutBuffer[buffered++]=sysex[i++] & 0x7f; - //usb_midi_tx((uint32 *)sysexOutBuffer, 1); - bytes2send-=3; - } - //if (bytes2send>3) { // this should already be covered above. - // return 0; - //} - sysexOutBuffer[buffered++] = CIN_SYSEX+bytes2send; - j=3; - while((bytes2send--)>1) { - sysexOutBuffer[buffered++]= sysex[i++] & 0x7f; - j--; - } - - sysexOutBuffer[buffered++] = MIDIv1_SYSEX_END; - i++; - j--; - - while (j--) { - sysexOutBuffer[buffered++]=0; // pad packets (probably unnecisary) - // if we eliminate this then must add j to math below. - } - usb_midi_tx((uint32 *)sysexOutBuffer, buffered/4); - return i; -} - - - -#define DEBUGGER_MMA_ID1 125 -#define DEBUGGER_MMA_ID2 51 -#define DEBUGGER_MMA_ID3 51 - -uint8 debugSysexPrelude[]= { - MIDIv1_SYSEX_START, - DEBUGGER_MMA_ID1, - DEBUGGER_MMA_ID2, //2 - //-- - DEBUGGER_MMA_ID3, - LEAFLABS_MMA_VENDOR_1, - LEAFLABS_MMA_VENDOR_2,//length 5 - //--- - LEAFLABS_MMA_VENDOR_3,//length - 0x00,//channel or id - 0x00,//severity 8 - //--- -}; - -/* - * this should probably be in a different space but if we put it here we can share a buffer and - * most of the code from above. - - */ -uint32 usb_midi_send_debug_string(uint8 *string, uint32 bytes2send) { - - if (bytes2send<1) - return 0; - - int j=1; - uint32 i=0; - uint32 buffered=0; - for (i=0; i<9; i++) { - sysexOutBuffer[buffered++]= CIN_SYSEX; - sysexOutBuffer[buffered++]=debugSysexPrelude[i++]; - sysexOutBuffer[buffered++]=debugSysexPrelude[i++]; - sysexOutBuffer[buffered++]=debugSysexPrelude[i++]; - } - j=0;i=0; - - bytes2send++; // make room for end of sysex - - if ((bytes2send + buffered) > (SYSEX_OUT_BUFFER_LENGTH - 4)) { - return 0; // if its to big then fahgetaboutit - } - while (bytes2send > 3 /*&& buffered<=SYSEX_OUT_BUFFER_LENGTH */) { - sysexOutBuffer[buffered++]=CIN_SYSEX; - sysexOutBuffer[buffered++]=string[i++] & 0x7f; - sysexOutBuffer[buffered++]=string[i++] & 0x7f; - sysexOutBuffer[buffered++]=string[i++] & 0x7f; - bytes2send-=3; - } - //if (bytes2send>3) { // this should already be covered above. - // return 0; - //} - sysexOutBuffer[buffered++] = CIN_SYSEX+bytes2send; - j=3; - while((bytes2send--)>1) { - sysexOutBuffer[buffered++]= string[i++] & 0x7f; - j--; - } - - sysexOutBuffer[buffered++] = MIDIv1_SYSEX_END; - //i++; // returns sent minux - j--; - - while (j--) { - sysexOutBuffer[buffered++]=0; // pad packets (probably unnecisary) - // if we eliminate this then must add j to math below. - } - usb_midi_tx((uint32 *)sysexOutBuffer, buffered/4); - return i; -} - - - - - +#endif diff --git a/support/ld/extra_libs.inc b/support/ld/extra_libs.inc new file mode 100644 index 0000000..1216f97 --- /dev/null +++ b/support/ld/extra_libs.inc @@ -0,0 +1 @@ +/* toolchain specific stuff */ diff --git a/support/ld/stm32/mem/sram_112k_flash_768k/mem-jtag.inc b/support/ld/stm32/mem/sram_112k_flash_768k/mem-jtag.inc new file mode 100644 index 0000000..d62fb7a --- /dev/null +++ b/support/ld/stm32/mem/sram_112k_flash_768k/mem-jtag.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 768K +} diff --git a/support/ld/stm32/mem/sram_112k_flash_768k/mem-ram.inc b/support/ld/stm32/mem/sram_112k_flash_768k/mem-ram.inc new file mode 100644 index 0000000..d21f17c --- /dev/null +++ b/support/ld/stm32/mem/sram_112k_flash_768k/mem-ram.inc @@ -0,0 +1,5 @@ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 112K + rom (rx) : ORIGIN = 0x08000000, LENGTH = 0K +} diff --git a/wirish/boards.cpp b/wirish/boards.cpp index e053245..a693fa6 100644 --- a/wirish/boards.cpp +++ b/wirish/boards.cpp @@ -143,15 +143,11 @@ static void setup_clocks(void) { * These addresses are where usercode starts when a bootloader is * present. If no bootloader is present, the user NVIC usually starts * at the Flash base address, 0x08000000. - * - * FIXME Let the build specify the vector table address numerically to - * avoid having these magic values -- some people have been fixing up - * the bootloader so it uses less space. */ #define USER_ADDR_ROM 0x08005000 #define USER_ADDR_RAM 0x20000C00 extern char __text_start__; - + static void setup_nvic(void) { #ifdef VECT_TAB_FLASH nvic_init(USER_ADDR_ROM, 0); @@ -163,7 +159,8 @@ static void setup_nvic(void) { // A numerically supplied value nvic_init((uint32)VECT_TAB_ADDR, 0); #else - // Use the __text_start__ value from the linker scipt, this should be the start of the vector table + // Use the __text_start__ value from the linker script; this + // should be the start of the vector table. nvic_init((uint32)&__text_start__, 0); #endif } diff --git a/wirish/boards/maple/board.mk b/wirish/boards/maple/board.mk new file mode 100644 index 0000000..e31d777 --- /dev/null +++ b/wirish/boards/maple/board.mk @@ -0,0 +1,12 @@ +# Board specific make defines for Maple board + +CPU = cortex-m3 +ARCH = armv7-m +MCU_SERIES = stm32f1 +MCU = MCU_STM32F103RB +MEMORY = sram_20k_flash_128k +ifeq ($(TARGET),jtag) +DFUID = 0483:df11 +DFUALT = 0 +endif + diff --git a/wirish/stm32f1/boards_setup.cpp b/wirish/stm32f1/boards_setup.cpp index ca1a43c..11872d5 100644 --- a/wirish/stm32f1/boards_setup.cpp +++ b/wirish/stm32f1/boards_setup.cpp @@ -75,7 +75,7 @@ namespace wirish { __weak void board_setup_usb(void) { #if BOARD_HAVE_SERIALUSB - //SerialUSB.begin(); + SerialUSB.begin(); #endif } diff --git a/wirish/syscalls.c b/wirish/syscalls.c index 9a573a3..a3b6d2c 100644 --- a/wirish/syscalls.c +++ b/wirish/syscalls.c @@ -169,6 +169,7 @@ __weak char *fgets(char *s, int bufsize, void *f) { return s; } -__weak int _exit(int exitcode) { - while (1); +__weak void _exit(int exitcode) { + while (1) + ; } |
