spi.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /**
  2. * @license Licensed under the Apache License, Version 2.0 (the "License"):
  3. * http://www.apache.org/licenses/LICENSE-2.0
  4. */
  5. /**
  6. * @fileoverview Arduino ode generator for SPI library blocks.
  7. * The Arduino SPI library docs: http://arduino.cc/en/Reference/SPI
  8. */
  9. 'use strict';
  10. goog.provide('Blockly.Python.spi');
  11. goog.require('Blockly.Python');
  12. /**
  13. * Code generator for the SPI configuration block. It does not add any LoC to
  14. * the loop(), but it generates code for the setup() function.
  15. * Arduino code: #include <SPI.h>
  16. * setup() { SPI.setBitOrder(X);
  17. * SPI.setDataMode(Y);
  18. * SPI.setClockDivider(Z);
  19. * SPI.begin(); }
  20. * @param {!Blockly.Block} block Block to generate the code from.
  21. * @return {string} Completed code.
  22. */
  23. Blockly.Python['spi_setup'] = function(block) {
  24. var spiId = block.getFieldValue('SPI_ID');
  25. var spiShift = block.getFieldValue('SPI_SHIFT_ORDER');
  26. var spiClockDivide = block.getFieldValue('SPI_CLOCK_DIVIDE');
  27. var spiMode = block.getFieldValue('SPI_MODE');
  28. Blockly.Python.addInclude('spi', '#include <SPI.h>');
  29. Blockly.Python.addSetup('spi_order',
  30. spiId + '.setBitOrder(' + spiShift + ');', true);
  31. Blockly.Python.addSetup('spi_mode',
  32. spiId + '.setDataMode(' + spiMode + ');', true);
  33. Blockly.Python.addSetup('spi_div',
  34. spiId + '.setClockDivider(' + spiClockDivide + ');', true);
  35. Blockly.Python.addSetup('spi_begin',
  36. spiId + '.begin();', true);
  37. return '';
  38. };
  39. /**
  40. * Code generator for the SPI transfer block.
  41. * SPI bus can have several slaves, which are selected using a digital output
  42. * as a SS pin. This digital pin will be configured as a normal output.
  43. * Arduino code: #include <SPI.h>
  44. * setup { pinMode(X, OUTPUT); }
  45. * loop { digitalWrite(X, HIGH);
  46. * SPI.transfer(0);
  47. * digitalWrite(X, LOW); }
  48. * @param {!Blockly.Block} block Block to generate the code from.
  49. * @return {string} Completed code.
  50. */
  51. Blockly.Python['spi_transfer'] = function(block) {
  52. var spiId = block.getFieldValue('SPI_ID');
  53. var spiSs = block.getFieldValue('SPI_SS');
  54. var spiData = Blockly.Python.valueToCode(
  55. block, 'SPI_DATA', Blockly.Python.ORDER_ATOMIC) || '0';
  56. Blockly.Python.addInclude('spi', '#include <SPI.h>');
  57. Blockly.Python.addSetup('spi_begin', spiId + '.begin();', false);
  58. // Reserve SPI pins MOSI, MISO, and SCK
  59. var spiPins = Blockly.Python.Boards.selected.spiPins[spiId];
  60. for (var i = 0; i < spiPins.length; i++) {
  61. Blockly.Python.reservePin(block, spiPins[i][1],
  62. Blockly.Python.PinTypes.SPI, 'SPI ' + spiPins[i][0]);
  63. }
  64. // Configure the Slave Select as a normal output if a pin is used
  65. if (spiSs !== 'none') {
  66. Blockly.Python.reservePin(
  67. block, spiSs, Blockly.Python.PinTypes.OUTPUT, 'SPI Slave pin');
  68. var setupCode = 'pinMode(' + spiSs + ', OUTPUT);';
  69. Blockly.Python.addSetup('io_' + spiSs, setupCode, false);
  70. } // else means the SS pin is always set for the device
  71. // Add the code, but only use a SS pin if one is selected
  72. var code = [];
  73. if (spiSs !== 'none') {
  74. code.push('digitalWrite(' + spiSs + ', HIGH);');
  75. }
  76. code.push(spiId + '.transfer(' + spiData + ');');
  77. if (spiSs !== 'none') {
  78. code.push('digitalWrite(' + spiSs + ', LOW);');
  79. }
  80. return code.join('\n') + '\n';
  81. };
  82. /**
  83. * Code generator for the SPI transfer block with a return value.
  84. * The rest is the same as the spi_transfer block.
  85. * @param {!Blockly.Block} block Block to generate the code from.
  86. * @return {string} Completed code.
  87. */
  88. Blockly.Python['spi_transfer_return'] = function(block) {
  89. var spiId = block.getFieldValue('SPI_ID');
  90. var spiSs = block.getFieldValue('SPI_SS');
  91. var spiData = Blockly.Python.valueToCode(
  92. block, 'SPI_DATA', Blockly.Python.ORDER_ATOMIC) || '0';
  93. // The spi_transfer block invoked to generate all setup stuff, code discarded
  94. var spiTransferOnlyCode = Blockly.Python['spi_transfer'](block);
  95. if (spiSs === 'none') {
  96. var code = spiId + '.transfer(' + spiData + ')';
  97. } else {
  98. var func = [
  99. 'int ' + Blockly.Python.DEF_FUNC_NAME + '() {',
  100. ' int spiReturn = 0;',
  101. ' digitalWrite(' + spiSs + ', HIGH);',
  102. ' spiReturn = ' + spiId + '.transfer(' + spiData + ');',
  103. ' digitalWrite(' + spiSs + ', LOW);',
  104. ' return spiReturn;',
  105. '}'];
  106. var functionName = Blockly.Python.addFunction(
  107. 'spiReturnSlave' + spiSs, func.join('\n'));
  108. var code = functionName + '()';
  109. }
  110. return [code, Blockly.Python.ORDER_UNARY_POSTFIX];
  111. };