Guest User

Gpio16BitAccessMode_64K_48_83_83

a guest
Apr 8th, 2014
107
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2.  * This file is a part of the open source stm32plus library.
  3.  * Copyright (c) 2011,2012,2013,2014 Andy Brown <www.andybrown.me.uk>
  4.  * Please see website for licensing terms.
  5.  */
  6.  
  7. #pragma once
  8.  
  9.  
  10. namespace stm32plus {
  11.   namespace display {
  12.  
  13.  
  14.     /**
  15.      * Specialisation for 48Mhz HCLK, 64K colour mode, 83ns low and 83ns high write cycle periods.
  16.      * The 20.8ns HCLK means that we actually achieve 83.3ns (+/- clock accuracy).
  17.      * This driver is intended for use with the 48MHz products, for example the F0 Discovery board.
  18.      */
  19.  
  20.     template<class TPinPackage>
  21.     class Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83> {
  22.  
  23.       protected:
  24.         uint32_t _controlSetAddress;
  25.         uint32_t _controlResetAddress;
  26.         uint32_t _portOutputRegister;
  27.         uint16_t _wr;
  28.         uint16_t _rs;
  29.         uint32_t _jump;
  30.  
  31.       public:
  32.         Gpio16BitAccessMode();
  33.  
  34.         void reset() const;
  35.  
  36.         void writeCommand(uint16_t command) const;
  37.         void writeCommand(uint16_t command,uint16_t parameter) const;
  38.         void writeData(uint16_t value) const;
  39.         void writeDataAgain(uint16_t value) const;
  40.         void writeMultiData(uint32_t howMuch,uint16_t value) const __attribute__((noinline));
  41.  
  42.         void rawTransfer(const void *buffer,uint32_t numWords) const;
  43.     };
  44.  
  45.  
  46.     /**
  47.      * Constructor
  48.      */
  49.  
  50.     template<class TPinPackage>
  51.     inline Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::Gpio16BitAccessMode() {
  52.  
  53.       // the assembly code needs these
  54.  
  55.       _rs=TPinPackage::Pin_RS;
  56.       _wr=TPinPackage::Pin_WR;
  57.  
  58.       // these are the addresses of the reset/set registers in the normal peripheral region.
  59.  
  60. #if defined(STM32PLUS_F1) || defined(STM32PLUS_F0)
  61.       _controlResetAddress=TPinPackage::Port_CONTROL+offsetof(GPIO_TypeDef,BRR);
  62.       _controlSetAddress=TPinPackage::Port_CONTROL+offsetof(GPIO_TypeDef,BSRR);
  63. #elif defined(STM32PLUS_F4)
  64.       _controlResetAddress=TPinPackage::Port_CONTROL+offsetof(GPIO_TypeDef,BSRRH);
  65.       _controlSetAddress=TPinPackage::Port_CONTROL+offsetof(GPIO_TypeDef,BSRRL);
  66. #else
  67. #error Unsupported MCU
  68. #endif
  69.  
  70.       // this is the address of the data output ODR register in the normal peripheral region.
  71.  
  72.       _portOutputRegister=TPinPackage::Port_DATA+offsetof(GPIO_TypeDef,ODR);
  73.  
  74.       // all 16 port pins to output, 50MHz slew rate
  75.  
  76.       GpioPinInitialiser::initialise((GPIO_TypeDef *)TPinPackage::Port_DATA,
  77.                                      0xffff,
  78.                                      Gpio::OUTPUT);
  79.  
  80.       // control pins to output
  81.  
  82.       GpioPinInitialiser::initialise((GPIO_TypeDef *)TPinPackage::Port_CONTROL,
  83.                                      TPinPackage::Pin_RS | TPinPackage::Pin_WR | TPinPackage::Pin_RESET,
  84.                                      Gpio::OUTPUT);
  85.  
  86.       // WR must start as HIGH
  87.  
  88.       GPIO_SetBits((GPIO_TypeDef *)TPinPackage::Port_CONTROL,TPinPackage::Pin_WR);
  89.     }
  90.  
  91.  
  92.     /**
  93.      * Hard-reset the panel
  94.      */
  95.  
  96.     template<class TPinPackage>
  97.     inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::reset() const {
  98.  
  99.       GPIO_TypeDef *port;
  100.  
  101.       // let the power stabilise
  102.  
  103.       MillisecondTimer::delay(10);
  104.  
  105.       // reset sequence
  106.  
  107.       port=(GPIO_TypeDef *)TPinPackage::Port_CONTROL;
  108.  
  109.       GPIO_SetBits(port,TPinPackage::Pin_RESET);
  110.       MillisecondTimer::delay(5);
  111.       GPIO_ResetBits(port,TPinPackage::Pin_RESET);
  112.       MillisecondTimer::delay(50);
  113.       GPIO_SetBits(port,TPinPackage::Pin_RESET);
  114.       MillisecondTimer::delay(50);
  115.     }
  116.  
  117.  
  118.     /**
  119.      * Write a command
  120.      * @param command The command register
  121.      */
  122.  
  123.     template<class TPinPackage>
  124.     inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::writeCommand(uint16_t command) const {
  125.  
  126.       __asm volatile(
  127.         " str  %[value], [%[data]]          \n\t"     // port <= value
  128.         " str  %[rs],    [%[creset], #0]    \n\t"     // [rs] = 0
  129.         " str  %[wr],    [%[creset], #0]    \n\t"     // [wr] = 0
  130.         " str  %[wr],    [%[cset], #0]      \n\t"     // [wr] = 1
  131.         :: [creset]   "l" (_controlResetAddress),     // the control reset address
  132.            [cset]     "l" (_controlSetAddress),       // the control set address
  133.            [data]     "l" (_portOutputRegister),      // the data port
  134.            [wr]       "l" (_wr),                      // WR pin bit
  135.            [rs]       "l" (_rs),                      // RS pin bit
  136.            [value]    "l" (command)                   // input value
  137.       );
  138.     }
  139.  
  140.  
  141.     /**
  142.      * Write a command and its parameter (convenience function)
  143.      * @param command The command register
  144.      * @param parameter The register parameter
  145.      */
  146.  
  147.     template<class TPinPackage>
  148.     inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::writeCommand(uint16_t command,uint16_t parameter) const {
  149.       writeCommand(command);
  150.       writeData(parameter);
  151.     }
  152.  
  153.  
  154.     /**
  155.      * Write a data value
  156.      * @param value The data value to write
  157.      */
  158.  
  159.     template<class TPinPackage>
  160.     inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::writeData(uint16_t value) const {
  161.  
  162.       __asm volatile(
  163.         " str  %[value], [%[data]]          \n\t"     // port <= value
  164.         " str  %[rs],    [%[cset], #0]      \n\t"     // [rs] = 1
  165.         " str  %[wr],    [%[creset], #0]    \n\t"     // [wr] = 0
  166.         " str  %[wr],    [%[cset], #0]      \n\t"     // [wr] = 1
  167.         :: [creset]   "l" (_controlResetAddress),     // the control reset address
  168.            [cset]     "l" (_controlSetAddress),       // the control set address
  169.            [data]     "l" (_portOutputRegister),      // the data port
  170.            [wr]       "l" (TPinPackage::Pin_WR),      // WR pin bit
  171.            [rs]       "l" (TPinPackage::Pin_RS),      // RS pin bit
  172.            [value]    "l" (value)                     // input value
  173.       );
  174.     }
  175.  
  176.  
  177.     /**
  178.      * Write the same data value that we have recently written out. This is one of our optimisation
  179.      * points. We don't have to do the whole 8080 transaction again and can just toggle WR.
  180.      * @param value The data value to write
  181.      */
  182.  
  183.     template<class TPinPackage>
  184.     inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::writeDataAgain(uint16_t /* value */) const {
  185.  
  186.       __asm volatile(
  187.         " str  %[wr], [%[creset], #0]   \n\t"       // [wr] = 0
  188.         " str  %[wr], [%[cset], #0]     \n\t"       // [wr] = 1
  189.         :: [creset]   "l" (_controlResetAddress),   // the control reset address
  190.            [cset]     "l" (_controlSetAddress),     // the control set address
  191.            [wr]       "l" (TPinPackage::Pin_WR)     // WR pin bit
  192.       );
  193.     }
  194.  
  195.  
  196.     /**
  197.      * Write a batch of the same data values to the XMEM interface using GPIO. The values are written out in a
  198.      * highly optimised loop in bursts of 40 at a time. This value seems a good trade off between flash usage
  199.      * and speed. Note the use of %= labels so that inlining doesn't produce duplicate names.
  200.      * @param howMuch The number of 16-bit values to write
  201.      * @param value The data value to write
  202.      */
  203.  
  204.     template<class TPinPackage>
  205.     __attribute__((noinline)) inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::writeMultiData(uint32_t howMuch,uint16_t value) const {
  206.  
  207.       // F0 compatibility : value, data, rs are only needed at the start so move
  208.       // them to own asm section so gcc doesn't have to find so many registers
  209.       // in the next block
  210.  
  211.       __asm volatile(
  212.         "str  %[value], [%[data]]                       \n\t"     // port <= value
  213.         "str  %[rs],    [%[cset], #0]                   \n\t"     // [rs] = 1
  214.         :: [rs]       "l" (TPinPackage::Pin_RS),      // RS pin bit
  215.            [value]    "l" (value),                    // input value
  216.            [cset]     "l" (_controlSetAddress),       // the control set address
  217.            [data]     "l" (_portOutputRegister)       // the data port
  218.       );
  219.  
  220.       // this is the main block
  221.  
  222.       __asm volatile(
  223.           "    cmp  %[howmuch], #40                       \n\t"     // if less than 40 then go straight
  224.           "    blo  lastlot%=                             \n\t"     // to the finishing off stage
  225.  
  226.           // the following loop shows the fastest that you can toggle a GPIO pin
  227.           // on the STM32.
  228.  
  229.           "batchloop%=:                                   \n\t"
  230.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  231.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  232.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  233.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  234.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  235.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  236.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  237.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  238.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  239.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  240.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  241.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  242.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  243.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  244.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  245.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  246.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  247.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  248.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  249.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  250.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  251.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  252.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  253.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  254.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  255.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  256.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  257.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  258.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  259.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  260.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  261.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  262.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  263.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  264.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  265.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  266.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  267.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  268.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  269.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  270.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  271.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  272.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  273.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  274.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  275.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  276.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  277.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  278.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  279.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  280.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  281.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  282.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  283.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  284.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  285.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  286.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  287.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  288.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  289.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  290.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  291.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  292.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  293.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  294.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  295.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  296.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  297.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  298.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  299.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  300.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  301.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  302.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  303.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  304.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  305.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  306.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  307.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  308.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  309.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  310.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  311.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  312.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  313.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  314.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  315.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  316.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  317.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  318.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  319.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  320.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  321.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  322.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  323.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  324.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  325.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  326.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  327.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  328.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  329.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  330.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  331.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  332.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  333.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  334.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  335.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  336.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  337.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  338.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  339.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  340.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  341.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  342.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  343.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  344.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  345.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  346.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  347.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  348.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  349.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  350.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  351.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  352.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  353.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  354.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  355.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  356.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  357.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  358.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  359.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  360.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  361.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  362.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  363.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  364.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  365.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  366.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  367.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  368.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  369.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  370.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  371.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  372.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  373.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  374.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  375.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  376.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  377.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  378.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  379.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  380.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  381.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  382.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  383.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  384.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  385.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  386.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  387.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  388.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  389.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  390.  
  391.           "    sub  %[howmuch], #40                       \n\t"     // subtract 40 from howMuch
  392.           "    cmp  %[howmuch], #40                       \n\t"     // if howMuch >= 40 then go back for another batch
  393.           "    bhs  batchloop%=                           \n\t"
  394.  
  395.           "lastlot%=:                                     \n\t"
  396.           "    ldr %[jump],    =finished%=                \n\t"     // load 'jump' with the address of the end
  397.           "    lsl %[howmuch], #3                         \n\t"     // multiply remaining by 8 and
  398.           "    sub %[jump],    %[howmuch]                 \n\t"     // subtract from the 'jump' target
  399.           "    add %[jump],    #1                         \n\t"     // set thumb mode (bit 0=1)
  400.           "    bx  %[jump]                                \n\t"     // indirect jump forward into the last lot
  401.  
  402.           // there are 39 writes here
  403.  
  404.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  405.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  406.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  407.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  408.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  409.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  410.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  411.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  412.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  413.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  414.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  415.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  416.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  417.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  418.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  419.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  420.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  421.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  422.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  423.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  424.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  425.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  426.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  427.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  428.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  429.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  430.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  431.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  432.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  433.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  434.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  435.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  436.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  437.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  438.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  439.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  440.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  441.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  442.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  443.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  444.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  445.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  446.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  447.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  448.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  449.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  450.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  451.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  452.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  453.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  454.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  455.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  456.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  457.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  458.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  459.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  460.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  461.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  462.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  463.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  464.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  465.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  466.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  467.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  468.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  469.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  470.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  471.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  472.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  473.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  474.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  475.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  476.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  477.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  478.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  479.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  480.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  481.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  482.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  483.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  484.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  485.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  486.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  487.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  488.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  489.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  490.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  491.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  492.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  493.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  494.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  495.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  496.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  497.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  498.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  499.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  500.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  501.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  502.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  503.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  504.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  505.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  506.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  507.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  508.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  509.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  510.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  511.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  512.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  513.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  514.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  515.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  516.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  517.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  518.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  519.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  520.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  521.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  522.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  523.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  524.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  525.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  526.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  527.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  528.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  529.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  530.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  531.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  532.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  533.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  534.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  535.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  536.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  537.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  538.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  539.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  540.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  541.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  542.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  543.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  544.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  545.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  546.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  547.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  548.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  549.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  550.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  551.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  552.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  553.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  554.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  555.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  556.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  557.           "    str  %[wr], [%[creset], #0]                \n\t"     // [wr] = 0
  558.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  559.           "    str  %[wr], [%[cset], #0]                  \n\t"     // [wr] = 1
  560.  
  561.           "finished%=:                                    \n\t"
  562.  
  563.           :: [creset]   "l" (_controlResetAddress),     // the control reset address
  564.              [cset]     "l" (_controlSetAddress),       // the control set address
  565.              [wr]       "l" (TPinPackage::Pin_WR),      // WR pin bit
  566.              [jump]     "l" (_jump),                    // holds calculated indirect jump target
  567.              [howmuch]  "l" (howMuch)                   // number of pixels to write
  568.       );
  569.     }
  570.  
  571.  
  572.     /**
  573.      * Write out a raw block of data from memory
  574.      * @param buffer Where to read from
  575.      * @param numWords The number of 16-bit words
  576.      */
  577.  
  578.     template<class TPinPackage>
  579.     inline void Gpio16BitAccessMode<TPinPackage,COLOURS_16BIT,48,83,83>::rawTransfer(const void *buffer,uint32_t numWords) const {
  580.  
  581.       const uint16_t *ptr=static_cast<const uint16_t *>(buffer);
  582.  
  583.       while(numWords--)
  584.         writeData(*ptr++);
  585.     }
  586.   }
  587. }
RAW Paste Data