Advertisement
Guest User

Untitled

a guest
May 28th, 2012
54
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.57 KB | None | 0 0
  1. #include "dma_udp_private.h"
  2.  
  3. #include <string.h>
  4.  
  5. #include "../../libmaple/dma.h"
  6. #include "../../libmaple/spi.h"
  7.  
  8. void setSS ();
  9. void restSS ();
  10.  
  11. static uint8_t spi_tx_dma_buf [2048];
  12. static uint8_t spi_rx_dma_buf [2048];
  13.  
  14. volatile uint8_t spi_dma_done;
  15.  
  16. void
  17. spi_dma_irq (void)
  18. {
  19.     spi_dma_done = 1;
  20. }
  21.  
  22. void
  23. spi_dma_run (uint16_t len)
  24. {
  25.     spi_dma_done = 0;
  26.  
  27.     dma_set_num_transfers (DMA1, DMA_CH5, len); // Tx
  28.     dma_set_num_transfers (DMA1, DMA_CH4, len); // Rx
  29.  
  30.     dma_enable (DMA1, DMA_CH4); // Rx
  31.     dma_enable (DMA1, DMA_CH5); // Tx
  32. }
  33.  
  34. void
  35. spi_dma_block ()
  36. {
  37.     while (!spi_dma_done)
  38.         ;
  39.  
  40.     dma_disable (DMA1, DMA_CH5); // Tx
  41.     dma_disable (DMA1, DMA_CH4); // Rx
  42. }
  43.  
  44. void
  45. _dma_write (uint16_t addr, uint8_t *dat, uint16_t len)
  46. {
  47.     uint8_t *buf = spi_tx_dma_buf;
  48.     uint16_t i;
  49.  
  50.     *buf++ = addr >> 8;
  51.     *buf++ = addr & 0xFF;
  52.     *buf++ = (0x80 | ((len & 0x7F00) >> 8));
  53.     *buf++ = len & 0x00FF;
  54.    
  55.     memcpy (buf, dat, len);
  56.     buf += len;
  57.  
  58.     setSS ();
  59.     spi_dma_run (buf-spi_tx_dma_buf);
  60.     spi_dma_block ();
  61.     resetSS ();
  62. }
  63.  
  64. uint8_t *
  65. _dma_write_append (uint8_t *buf, uint16_t addr, uint8_t *dat, uint16_t len)
  66. {
  67.     uint16_t i;
  68.  
  69.     *buf++ = addr >> 8;
  70.     *buf++ = addr & 0xFF;
  71.     *buf++ = (0x80 | ((len & 0x7F00) >> 8));
  72.     *buf++ = len & 0x00FF;
  73.    
  74.     memcpy (buf, dat, len);
  75.     buf += len;
  76.  
  77.     return buf;
  78. }
  79.  
  80. void
  81. _dma_write_nonblocking_in (uint8_t *buf)
  82. {
  83.     setSS ();
  84.     spi_dma_run (buf-spi_tx_dma_buf);
  85. }
  86.  
  87. void
  88. _dma_write_nonblocking_out ()
  89. {
  90.     spi_dma_block ();
  91.     resetSS ();
  92. }
  93.  
  94. void
  95. _dma_read (uint16_t addr, uint8_t *dat, uint16_t len)
  96. {
  97.     uint8_t *buf = spi_tx_dma_buf;
  98.     uint16_t i;
  99.  
  100.     *buf++ = addr >> 8;
  101.     *buf++ = addr & 0xFF;
  102.     *buf++ = (0x00 | ((len & 0x7F00) >> 8));
  103.     *buf++ = len & 0x00FF;
  104.    
  105.     memset (buf, 0x00, len);
  106.     buf += len;
  107.  
  108.     setSS ();
  109.     spi_dma_run (buf-spi_tx_dma_buf);
  110.     spi_dma_block ();
  111.     resetSS ();
  112.  
  113.     memcpy (dat, &spi_rx_dma_buf[4], len);
  114. }
  115.  
  116. void
  117. _dma_write_sock (uint8_t sock, uint16_t addr, uint8_t *dat, uint16_t len)
  118. {
  119.     // transform relative socket registry address to absolute registry address
  120.     _dma_write (CH_BASE + sock*CH_SIZE + addr, dat, len);
  121. }
  122.  
  123. uint8_t *
  124. _dma_write_sock_append (uint8_t *buf, uint8_t sock, uint16_t addr, uint8_t *dat, uint16_t len)
  125. {
  126.     // transform relative socket registry address to absolute registry address
  127.     return _dma_write_append (buf, CH_BASE + sock*CH_SIZE + addr, dat, len);
  128. }
  129.  
  130. void
  131. _dma_write_sock_16 (uint8_t sock, uint16_t addr, uint16_t dat)
  132. {
  133.     uint8_t flag;
  134.     flag = dat >> 8;
  135.     _dma_write_sock (sock, addr, &flag, 1);
  136.     flag = dat & 0xFF;
  137.     _dma_write_sock (sock, addr+1, &flag, 1);
  138. }
  139.  
  140. uint8_t *
  141. _dma_write_sock_16_append (uint8_t *buf, uint8_t sock, uint16_t addr, uint16_t dat)
  142. {
  143.     uint8_t flag;
  144.     flag = dat >> 8;
  145.     buf = _dma_write_sock_append (buf, sock, addr, &flag, 1);
  146.     flag = dat & 0xFF;
  147.     return _dma_write_sock_append (buf, sock, addr+1, &flag, 1);
  148. }
  149.  
  150. void
  151. _dma_read_sock (uint8_t sock, uint16_t addr, uint8_t *dat, uint16_t len)
  152. {
  153.     // transform relative socket registry address to absolute registry address
  154.     _dma_read (CH_BASE + sock*CH_SIZE + addr, dat, len);
  155. }
  156.  
  157. void
  158. _dma_read_sock_16 (int8_t sock, uint16_t addr, uint16_t *dat)
  159. {
  160.     uint8_t flag;
  161.     _dma_read_sock (sock, addr, &flag, 1);
  162.     *dat = flag << 8;
  163.     _dma_read_sock (sock, addr+1, &flag, 1);
  164.     *dat += flag;
  165. }
  166.  
  167. void
  168. dma_udp_init (uint8_t *mac, uint8_t *ip, uint8_t *gateway, uint8_t *subnet)
  169. {
  170.     // set up dma for SPI2RX
  171.     dma_setup_transfer (
  172.         DMA1,
  173.         DMA_CH4,
  174.         &SPI2->regs->DR,
  175.         DMA_SIZE_8BITS,
  176.         spi_rx_dma_buf,
  177.         DMA_SIZE_8BITS,
  178.         DMA_MINC_MODE | DMA_TRNS_CMPLT
  179.     );
  180.     dma_set_priority (DMA1, DMA_CH4, DMA_PRIORITY_HIGH);
  181.     dma_attach_interrupt (DMA1, DMA_CH4, spi_dma_irq);
  182.  
  183.     // set up dma for SPI2TX
  184.     dma_setup_transfer (
  185.         DMA1,
  186.         DMA_CH5,
  187.         &SPI2->regs->DR,
  188.         DMA_SIZE_8BITS,
  189.         spi_tx_dma_buf,
  190.         DMA_SIZE_8BITS,
  191.         DMA_MINC_MODE | DMA_FROM_MEM
  192.     );
  193.     dma_set_priority (DMA1, DMA_CH5, DMA_PRIORITY_HIGH);
  194.  
  195.     // init w5200
  196.     uint8_t i;
  197.     uint8_t flag;
  198.  
  199.     flag = 1 << RST;
  200.     _dma_write (MR, &flag, 1);
  201.  
  202.     flag = 2;
  203.   for (i=0; i<MAX_SOCK_NUM; i++) {
  204.         _dma_write_sock (i, SnTX_MS, &flag, 1); // TX_MEMSIZE
  205.         _dma_write_sock (i, SnRX_MS, &flag, 1); // RX_MEMSIZE
  206.   }
  207.  
  208.     // set MAC address of device
  209.     _dma_write (SHAR, mac, 6);
  210.  
  211.     // set IP of device
  212.     _dma_write (SIPR, ip, 4);
  213.  
  214.     // set Gateway of device
  215.     _dma_write (GAR, gateway, 4);
  216.  
  217.     // set Subnet Mask of device
  218.     _dma_write (SUBR, subnet, 4);
  219. }
  220.  
  221. void
  222. dma_udp_begin (uint8_t sock, uint16_t port)
  223. {
  224.     uint8_t flag;
  225.  
  226.     // close socket
  227.     flag = SnCR_CLOSE;
  228.     _dma_write_sock (sock, SnCR, &flag, 1);
  229.     do _dma_read_sock (sock, SnSR, &flag, 1);
  230.     while (flag != SnSR_CLOSED);
  231.  
  232.     // clear interrupt?
  233.     _dma_write_sock (sock, SnIR, &flag, 1);
  234.  
  235.     // set socket mode to UDP
  236.     flag = SnMR_UDP;
  237.     _dma_write_sock (sock, SnMR, &flag, 1);
  238.  
  239.     // set outgoing port
  240.     _dma_write_sock_16 (sock, SnPORT, port);
  241.  
  242.     // open socket
  243.     flag = SnCR_OPEN;
  244.     _dma_write_sock (sock, SnCR, &flag, 1);
  245.     do _dma_read_sock (sock, SnSR, &flag, 1);
  246.     while (flag != SnSR_UDP);
  247. }
  248.  
  249. void
  250. dma_udp_set_remote (uint8_t sock, uint8_t *ip, uint16_t port)
  251. {
  252.     // set remote ip
  253.     _dma_write_sock (sock, SnDIPR, ip, 4);
  254.  
  255.     // set remote port
  256.     _dma_write_sock_16 (sock, SnDPORT, port);
  257. }
  258.  
  259. void
  260. dma_udp_send (uint8_t sock, uint8_t *dat, uint16_t len)
  261. {
  262.     uint16_t free;
  263.     _dma_read_sock_16 (sock, SnTX_FSR, &free);
  264.     if (len > free)
  265.         return;
  266.  
  267.     // move data to chip
  268.     uint16_t ptr;
  269.     _dma_read_sock_16 (sock, SnTX_WR, &ptr);
  270.   uint16_t offset = ptr & SMASK;
  271.     uint16_t SBASE = TXBUF_BASE + sock*SSIZE;
  272.   uint16_t dstAddr = offset + SBASE;
  273.  
  274.   if (offset + len > SSIZE)
  275.   {
  276.     // Wrap around circular buffer
  277.     uint16_t size = SSIZE - offset;
  278.         _dma_write (dstAddr, dat, size);
  279.         _dma_write (SBASE, dat+size, len-size);
  280.   }
  281.   else
  282.         _dma_write (dstAddr, dat, len);
  283.  
  284.   ptr += len;
  285.     _dma_write_sock_16 (sock, SnTX_WR, ptr);
  286.  
  287.     // send data
  288.     uint8_t flag;
  289.     flag = SnCR_SEND;
  290.     _dma_write_sock (sock, SnCR, &flag, 1);
  291.  
  292.     uint8_t ir;
  293.     do
  294.     {
  295.         _dma_read_sock (sock, SnIR, &ir, 1);
  296.         if (ir & SnIR_TIMEOUT)
  297.         {
  298.             flag = SnIR_SEND_OK | SnIR_TIMEOUT;
  299.             _dma_write_sock (sock, SnIR, &flag, 1);
  300.         }
  301.     } while ( (ir & SnIR_SEND_OK) != SnIR_SEND_OK);
  302.  
  303.     flag = SnIR_SEND_OK;
  304.     _dma_write_sock (sock, SnIR, &flag, 1);
  305. }
  306.  
  307. static struct {
  308.     uint16_t free;
  309.     uint16_t ptr;
  310.     uint16_t offset;
  311.     uint16_t SBASE;
  312.     uint16_t dstAddr;
  313. } mem;
  314.  
  315. void
  316. dma_udp_send_nonblocking_1 (uint8_t sock, uint8_t *dat, uint16_t len)
  317. {
  318.     _dma_read_sock_16 (sock, SnTX_FSR, &mem.free);
  319.  
  320.     if (len > mem.free)
  321.         return;
  322.  
  323.     // move data to chip
  324.     _dma_read_sock_16 (sock, SnTX_WR, &mem.ptr);
  325.   mem.offset = mem.ptr & SMASK;
  326.     mem.SBASE = TXBUF_BASE + sock*SSIZE;
  327.   mem.dstAddr = mem.offset + mem.SBASE;
  328. }
  329.  
  330. void
  331. dma_udp_send_nonblocking_2 (uint8_t sock, uint8_t *dat, uint16_t len)
  332. {
  333.     uint8_t *buf = spi_tx_dma_buf;
  334.  
  335.     if (len > mem.free)
  336.         return;
  337.  
  338.   if (mem.offset + len > SSIZE)
  339.   {
  340.     // Wrap around circular buffer
  341.     uint16_t size = SSIZE - mem.offset;
  342.         buf = _dma_write_append (buf, mem.dstAddr, dat, size);
  343.         buf = _dma_write_append (buf, mem.SBASE, dat+size, len-size);
  344.   }
  345.   else
  346.         buf = _dma_write_append (buf, mem.dstAddr, dat, len);
  347.  
  348.   mem.ptr += len;
  349.     buf = _dma_write_sock_16_append (buf, sock, SnTX_WR, mem.ptr);
  350.  
  351.     // send data
  352.     uint8_t flag;
  353.     flag = SnCR_SEND;
  354.     buf = _dma_write_sock_append (buf, sock, SnCR, &flag, 1);
  355.  
  356.     _dma_write_nonblocking_in (buf);
  357. }
  358.  
  359. void
  360. dma_udp_send_nonblocking_3 (uint8_t sock, uint8_t *dat, uint16_t len)
  361. {
  362.     if (len > mem.free)
  363.         return;
  364.  
  365.     _dma_write_nonblocking_out ();
  366.  
  367.     uint8_t flag;
  368.     uint8_t ir;
  369.     do
  370.     {
  371.         _dma_read_sock (sock, SnIR, &ir, 1);
  372.         if (ir & SnIR_TIMEOUT)
  373.         {
  374.             flag = SnIR_SEND_OK | SnIR_TIMEOUT;
  375.             _dma_write_sock (sock, SnIR, &flag, 1);
  376.         }
  377.     } while ( (ir & SnIR_SEND_OK) != SnIR_SEND_OK);
  378.  
  379.     flag = SnIR_SEND_OK;
  380.     _dma_write_sock (sock, SnIR, &flag, 1);
  381. }
  382.  
  383. uint16_t
  384. dma_udp_available (uint8_t sock)
  385. {
  386.     uint16_t len;
  387.     _dma_read_sock_16 (sock, SnRX_RSR, &len);
  388.     return len;
  389. }
  390.  
  391. void
  392. dma_udp_receive (uint8_t sock, uint8_t *buf, uint16_t len)
  393. {
  394.     uint16_t ptr;
  395.     _dma_read_sock_16 (sock, SnRX_RD, &ptr);
  396.  
  397.     uint16_t size;
  398.     uint16_t src_mask;
  399.     uint16_t src_ptr;
  400.     uint16_t RBASE = RXBUF_BASE + sock*RSIZE;
  401.  
  402.     src_mask = ptr & RMASK;
  403.     src_ptr = RBASE + src_mask;
  404.  
  405.     // read message
  406.     if ( (src_mask + len) > RSIZE)
  407.     {
  408.         size = RSIZE - src_mask;
  409.         _dma_read (src_ptr, buf, size);
  410.         _dma_read (RBASE, buf+size, len-size);
  411.     }
  412.     else
  413.         _dma_read (src_ptr, buf, len);
  414.  
  415.     ptr += len;
  416.     _dma_write_sock_16 (sock, SnRX_RD, ptr);
  417.  
  418.     uint8_t flag;
  419.     flag = SnCR_RECV;
  420.     _dma_write_sock (sock, SnCR, &flag, 1);
  421. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement