aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README14
-rw-r--r--libmaple/include/libmaple/usb.h1
-rw-r--r--libmaple/usb/stm32f1/usb.c196
-rw-r--r--libmaple/usb/stm32f1/usb_cdcacm.c1
-rw-r--r--libmaple/usb/stm32f1/usb_midi_device.c452
-rw-r--r--support/ld/extra_libs.inc1
-rw-r--r--support/ld/stm32/mem/sram_112k_flash_768k/mem-jtag.inc5
-rw-r--r--support/ld/stm32/mem/sram_112k_flash_768k/mem-ram.inc5
-rw-r--r--wirish/boards.cpp9
-rw-r--r--wirish/boards/maple/board.mk12
-rw-r--r--wirish/stm32f1/boards_setup.cpp2
-rw-r--r--wirish/syscalls.c5
12 files changed, 231 insertions, 472 deletions
diff --git a/README b/README
index 400e656..33ad1a2 100644
--- a/README
+++ b/README
@@ -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)
+ ;
}