Fork of the MODSERIAL library by Erik Olieman.
Fork of MODSERIAL by
Revision 36:b04ce87dc424, committed 2013-09-01
- Comitter:
- Sissors
- Date:
- Sun Sep 01 12:24:12 2013 +0000
- Parent:
- 35:9a41078f0488
- Child:
- 37:b90b20f78f04
- Commit message:
- See changelog
Changed in this revision
--- a/ChangeLog.c Fri Jul 12 15:56:20 2013 +0000 +++ b/ChangeLog.c Sun Sep 01 12:24:12 2013 +0000 @@ -1,4 +1,8 @@ /* $Id:$ +1.30 1st September 2013 + * Removed all DMA related code (not supported in this version currently) + * Minor bug fix + 1.29 12th July 2013 * Added KL25Z support + split code in device dependent and independent part
--- a/FLUSH.cpp Fri Jul 12 15:56:20 2013 +0000 +++ b/FLUSH.cpp Sun Sep 01 12:24:12 2013 +0000 @@ -39,7 +39,7 @@ buffer_overflow[type] = 0; switch(type) { case TxIrq: RESET_TX_FIFO; break; - case RxIrq: while(MODSERIAL_READABLE) char dummy = MODSERIAL_READ_REG; break; + case RxIrq: RESET_RX_FIFO; break; } MODSERIAL_IRQ_REG = irq_req; }
--- a/INIT.cpp Fri Jul 12 15:56:20 2013 +0000 +++ b/INIT.cpp Sun Sep 01 12:24:12 2013 +0000 @@ -41,9 +41,7 @@ setBase(); callbackInfo.setSerial(this); - - dmaSendChannel = -1; - moddma_p = (void *)NULL; + if ( _base != NULL ) { buffer_size[RxIrq] = rxSize;
--- a/MODSERIAL.h Fri Jul 12 15:56:20 2013 +0000 +++ b/MODSERIAL.h Sun Sep 01 12:24:12 2013 +0000 @@ -937,127 +937,7 @@ */ int upSizeBuffer(int size, IrqType type, bool memory_check); - /* - * If MODDMA is available the compile in code to handle sending - * an arbitary char buffer. Note, the parts before teh #ifdef - * are declared so that MODSERIAL can access then even if MODDMA - * isn't avaiable. Since MODDMA.h is only available at this point - * all DMA functionality must be declared inline in the class - * definition. - */ -public: - - int dmaSendChannel; - void *moddma_p; -#ifdef MODDMA_H - - MODDMA_Config *config; - - /** - * Set the "void pointer" moddma_p to be a pointer to a - * MODDMA controller class instance. Used to manage the - * data transfer of DMA configurations. - * - * @ingroup API - * @param p A pointer to "the" instance of MODDMA. - */ - void MODDMA(MODDMA *p) { moddma_p = p; } - - /** - * Send a char buffer to the Uarts TX system - * using DMA. This blocks regular library - * sending. - * - * @param buffer A char buffer of bytes to send. - * @param len The length of the buffer to send. - * @param dmaChannel The DMA channel to use, defaults to 7 - * @return MODDMA::Status MODDMA::ok if all went ok - */ - int dmaSend(char *buffer, int len, int dmaChannel = 7) - { - if (moddma_p == (void *)NULL) return -2; - class MODDMA *dma = (class MODDMA *)moddma_p; - - dmaSendChannel = dmaChannel & 0x7; - - uint32_t conn = MODDMA::UART0_Tx; - switch(_serial.index) { - case 0: conn = MODDMA::UART0_Tx; break; - case 1: conn = MODDMA::UART1_Tx; break; - case 2: conn = MODDMA::UART2_Tx; break; - case 3: conn = MODDMA::UART3_Tx; break; - } - - config = new MODDMA_Config; - config - ->channelNum ( (MODDMA::CHANNELS)(dmaSendChannel & 0x7) ) - ->srcMemAddr ( (uint32_t) buffer ) - ->transferSize ( len ) - ->transferType ( MODDMA::m2p ) - ->dstConn ( conn ) - ->attach_tc ( this, &MODSERIAL::dmaSendCallback ) - ->attach_err ( this, &MODSERIAL::dmaSendCallback ) - ; // config end - - // Setup the configuration. - if (dma->Setup(config) == 0) { - return -1; - } - - //dma.Enable( MODDMA::Channel_0 ); - dma->Enable( config->channelNum() ); - return MODDMA::Ok; - } - - /** - * Attach a callback to the DMA completion. - * - * @ingroup API - * @param fptr A function pointer to call - * @return this - */ - void attach_dmaSendComplete(void (*fptr)(MODSERIAL_IRQ_INFO *)) { - _isrDmaSendComplete.attach(fptr); - } - - /** - * Attach a callback to the DMA completion. - * - * @ingroup API - * @param tptr A template pointer to the calling object - * @param mptr A method pointer within the object to call. - * @return this - */ - template<typename T> - void attach_dmaSendComplete(T* tptr, void (T::*mptr)(MODSERIAL_IRQ_INFO *)) { - if((mptr != NULL) && (tptr != NULL)) { - _isrDmaSendComplete.attach(tptr, mptr); - } - } - - MODSERIAL_callback _isrDmaSendComplete; - -protected: - /** - * Callback for dmaSend(). - */ - void dmaSendCallback(void) - { - if (moddma_p == (void *)NULL) return; - class MODDMA *dma = (class MODDMA *)moddma_p; - - MODDMA_Config *config = dma->getConfig(); - dma->haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); - dma->Disable( (MODDMA::CHANNELS)config->channelNum() ); - if (dma->irqType() == MODDMA::TcIrq) dma->clearTcIrq(); - if (dma->irqType() == MODDMA::ErrIrq) dma->clearErrIrq(); - dmaSendChannel = -1; - _isrDmaSendComplete.call(&this->callbackInfo); - delete(config); - } - -#endif // MODDMA_H //DEVICE SPECIFIC FUNCTIONS:
--- a/PUTC.cpp Fri Jul 12 15:56:20 2013 +0000 +++ b/PUTC.cpp Sun Sep 01 12:24:12 2013 +0000 @@ -37,7 +37,7 @@ return 0; } - if ( MODSERIAL_WRITABLE && MODSERIAL_TX_BUFFER_EMPTY && dmaSendChannel == -1 ) { + if ( MODSERIAL_WRITABLE && MODSERIAL_TX_BUFFER_EMPTY ) { MODSERIAL_WRITE_REG = (uint32_t)c; } else {
--- a/example_dma.cpp Fri Jul 12 15:56:20 2013 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,144 +0,0 @@ -#ifdef COMPILE_EXAMPLE_CODE_MODSERIAL_MODDMA - -/* - * To run this test program, link p9 to p10 so the Serial loops - * back and receives characters it sends. - */ - -#include "mbed.h" - -/* Note, this example requires that you also import into the Mbed - compiler the MODDMA project as well as MODSERIAL - http://mbed.org/users/AjK/libraries/MODDMA/latest - MODDMA.h MUST come before MODSERIAL.h */ -#include "MODDMA.h" // <--- Declare first -#include "MODSERIAL.h" // Flollowed by MODSERIAL - -DigitalOut led1(LED1); -DigitalOut led2(LED2); -DigitalOut led3(LED3); -DigitalOut led4(LED4); - -MODSERIAL pc(USBTX, USBRX); - -/* - * As experiement, you can define MODSERIAL as show here and see what - * effects it has on the LEDs. - * - * MODSERIAL uart(TX_PIN, RX_PIN, 512); - * With this, the 512 characters sent can straight into the buffer - * vary quickly. This means LED1 is only on briefly as the TX buffer - * fills. - * - * MODSERIAL uart(TX_PIN, RX_PIN, 32); - * With this, the buffer is smaller than the default 256 bytes and - * therefore LED1 stays on much longer while the system waits for - * room in the TX buffer. - */ -MODSERIAL uart(TX_PIN, RX_PIN); - -MODDMA dma; - -// This function is called when a character goes from the TX buffer -// to the Uart THR FIFO register. -void txCallback(void) { - led2 = !led2; -} - -// This function is called when TX buffer goes empty -void txEmpty(void) { - led2 = 0; - pc.puts(" Done. "); -} - -void dmaComplete(void) { - led1 = 1; -} - -// This function is called when a character goes into the RX buffer. -void rxCallback(void) { - led3 = !led3; - pc.putc(uart.getc()); -} - -int main() { - char s1[] = " *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* "; - int c = 'A'; - - // Tell MODSERIAL where the MODDMA controller is. - pc.MODDMA( &dma ); - - // Ensure the baud rate for the PC "USB" serial is much - // higher than "uart" baud rate below. - pc.baud( PC_BAUD ); - - // Use a deliberatly slow baud to fill up the TX buffer - uart.baud(1200); - - uart.attach( &txCallback, MODSERIAL::TxIrq ); - uart.attach( &rxCallback, MODSERIAL::RxIrq ); - uart.attach( &txEmpty, MODSERIAL::TxEmpty ); - - // Loop sending characters. We send 512 - // which is twice the default TX/RX buffer size. - - led1 = 0; - - // Send the buffer s using DMA channel 7 - pc.attach_dmaSendComplete( &dmaComplete ); - pc.dmaSend( s1, sizeof(s1), MODDMA::Channel_7 ); - - for (int loop = 0; loop < 512; loop++) { - uart.printf("%c", c); - c++; - if (c > 'Z') c = 'A'; - } - - led1 = 0; // Show the end of sending by switching off LED1. - - // End program. Flash LED4. Notice how LED 2 and 3 continue - // to flash for a short period while the interrupt system - // continues to send the characters left in the TX buffer. - - while(1) { - led4 = !led4; - wait(0.25); - } -} - -/* - * Notes. Here is the sort of output you can expect on your PC/Mac/Linux host - * machine that is connected to the "pc" USB serial port. - * - * *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* *DMA* ABCDEFGHIJKLMNOPQRSTUVWXYZABCDE - * FGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZA - * BCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVW - * XYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRS - * TUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNO - * PQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJK - * LMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFG - * HIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQ Done. R - * - * Note how the DMA blocks the TX buffer sending under standard interrupt control. - * Not until the DMA transfer is complete will "normal" buffered TX sending resume. - * - * Of interest is that last "R" character after the system has said "Done." - * This comes from the fact that the TxEmpty callback is made when the TX buffer - * becomes empty. MODSERIAL makes use of the fact that the Uarts built into the - * LPC17xx device use a 16 byte FIFO on both RX and TX channels. This means that - * when the TxEmpty callback is made, the TX buffer is empty, but that just means - * the "last few characters" were written to the TX FIFO. So although the TX - * buffer has gone empty, the Uart's transmit system is still sending any remaining - * characters from it's TX FIFO. If you want to be truely sure all the characters - * you have sent have left the Mbed then call txIsBusy(); This function will - * return true if characters are still being sent. If it returns false after - * the Tx buffer is empty then all your characters have been sent. - * - * In a similar way, when characters are received into the RX FIFO, the entire - * FIFO contents is moved to the RX buffer, assuming there is room left in the - * RX buffer. If there is not, any remaining characters are left in the RX FIFO - * and will be moved to the RX buffer on the next interrupt or when the running - * program removes a character(s) from the RX buffer with the getc() method. - */ - -#endif