comparison pru_rtaudio.p @ 26:6d64ee8c0754 matrix_gpio

- fixed bug that caused the PRU to hang when opening a socket or an ssh connection. Bug was a typo in LBBO reg_gpio2_oe
author Giulio Moro <giuliomoro@yahoo.it>
date Sun, 10 May 2015 01:33:16 +0100
parents c98863e63174
children a9af130097e8
comparison
equal deleted inserted replaced
23:182ae9367104 26:6d64ee8c0754
272 .endm 272 .endm
273 273
274 .macro READ_GPIO_BITS 274 .macro READ_GPIO_BITS
275 .mparam gpio_data, gpio_num_bit, digital_bit, digital 275 .mparam gpio_data, gpio_num_bit, digital_bit, digital
276 QBBC DONE, digital, digital_bit //if the pin is set as an output, nothing to do here 276 QBBC DONE, digital, digital_bit //if the pin is set as an output, nothing to do here
277 SET r30.t14
278 QBBC CLEAR, gpio_data, gpio_num_bit 277 QBBC CLEAR, gpio_data, gpio_num_bit
279 SET digital, digital_bit+16 278 SET digital, digital_bit+16
280 QBA DONE 279 QBA DONE
281 CLEAR: 280 CLEAR:
282 CLR digital, digital_bit+16 281 CLR digital, digital_bit+16
283 QBA DONE 282 QBA DONE
284 DONE: 283 DONE:
285 CLR r30.t14
286 .endm 284 .endm
287 285
288 .macro SET_GPIO_BITS 286 .macro SET_GPIO_BITS
289 .mparam gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, digital_bit, digital //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT 287 .mparam gpio_oe, gpio_setdataout, gpio_cleardataout, gpio_num_bit, digital_bit, digital //sets the bits in GPIO_OE, GPIO_SETDATAOUT and GPIO_CLEARDATAOUT
290 //Remember that the GPIO_OE Output data enable register behaves as follows for each bit: 288 //Remember that the GPIO_OE Output data enable register behaves as follows for each bit:
328 //[31:16]: data(1=high, 0=low), [15:0]: direction (0=output, 1=input) ) 326 //[31:16]: data(1=high, 0=low), [15:0]: direction (0=output, 1=input) )
329 //Preparing the gpio_oe, gpio_cleardataout and gpio_setdataout for each module 327 //Preparing the gpio_oe, gpio_cleardataout and gpio_setdataout for each module
330 328
331 //load current status of GPIO_OE in reg_gpioX_oe 329 //load current status of GPIO_OE in reg_gpioX_oe
332 MOV reg_gpio1_oe, GPIO1 | GPIO_OE 330 MOV reg_gpio1_oe, GPIO1 | GPIO_OE
333 //takes ...ns to go through the next two instructions 331 //it takes 190ns to go through the next instruction
334 LBBO reg_gpio1_oe, reg_gpio1_oe, 0, 4 332 LBBO reg_gpio1_oe, reg_gpio1_oe, 0, 4
335 //GPIO1-start 333 //GPIO1-start
336 //process oe and datain and prepare dataout for GPIO1 334 //process oe and datain and prepare dataout for GPIO1
337 LDI reg_gpio1_setdataout, 0 335 LDI reg_gpio1_setdataout, 0
338 LDI reg_gpio1_cleardataout, 0 336 LDI reg_gpio1_cleardataout, 0
351 349
352 // reg_gpio1_oe is now unused, its register is taken by gpio2_cleardataout 350 // reg_gpio1_oe is now unused, its register is taken by gpio2_cleardataout
353 // reg_gpio1_datain now unused, its register is taken by gpio2_setdataout 351 // reg_gpio1_datain now unused, its register is taken by gpio2_setdataout
354 //GPIO2-start 352 //GPIO2-start
355 //load current status of GPIO_OE in reg_gpioX_oe 353 //load current status of GPIO_OE in reg_gpioX_oe
356 MOV reg_gpio2_oe, GPIO2 | GPIO_OE 354 MOV reg_gpio2_oe, GPIO2 | GPIO_OE
357 //takes ...ns to go through the next two instructions 355 //it takes 200ns to go through the next instructions
358 LBBO reg_gpio2_oe, reg_gpio1_oe, 0, 4 356 LBBO reg_gpio2_oe, reg_gpio2_oe, 0, 4
359 //process oe and datain and prepare dataout for GPIO2 357 //process oe and datain and prepare dataout for GPIO2
360 LDI reg_gpio2_setdataout, 0 358 LDI reg_gpio2_setdataout, 0
361 LDI reg_gpio2_cleardataout, 0 359 LDI reg_gpio2_cleardataout, 0
362 //map GPIO_ANALOG to gpio2 pins, affects reg_gpio2_oe, reg_gpio2_cleardataout, reg_gpio2_data, reg_digital 360 //map GPIO_ANALOG to gpio2 pins, affects reg_gpio2_oe, reg_gpio2_cleardataout, reg_gpio2_data, reg_digital
363 SET_GPIO2_BITS 2, 0 361 SET_GPIO2_BITS 2, 0
375 //GPIO2-end 373 //GPIO2-end
376 374
377 //load current inputs in reg_gpioX_datain 375 //load current inputs in reg_gpioX_datain
378 MOV reg_gpio1_datain, GPIO1 | GPIO_DATAIN 376 MOV reg_gpio1_datain, GPIO1 | GPIO_DATAIN
379 MOV reg_gpio2_datain, GPIO2 | GPIO_DATAIN 377 MOV reg_gpio2_datain, GPIO2 | GPIO_DATAIN
380 //takes ...ns to go through the next two instructions 378 //takes 375 nns to go through the next two instructions
381 LBBO reg_gpio1_datain, reg_gpio1_datain, 0, 4 379 LBBO reg_gpio1_datain, reg_gpio1_datain, 0, 4
382 LBBO reg_gpio2_datain, reg_gpio2_datain, 0, 4 380 LBBO reg_gpio2_datain, reg_gpio2_datain, 0, 4
383 //TODO: read inputs
384 READ_GPIO1_BITS 13, 4 381 READ_GPIO1_BITS 13, 4
385 READ_GPIO1_BITS 12, 5 382 READ_GPIO1_BITS 12, 5
386 READ_GPIO1_BITS 28, 6 383 READ_GPIO1_BITS 28, 6
387 READ_GPIO1_BITS 18, 7 384 READ_GPIO1_BITS 18, 7
388 READ_GPIO1_BITS 15, 8 385 READ_GPIO1_BITS 15, 8
405 //We can do this because we chose reg_gpio1_cleardataout and reg_gpioX_setdataout to be consecutive 402 //We can do this because we chose reg_gpio1_cleardataout and reg_gpioX_setdataout to be consecutive
406 //load the memory addresses to be written to 403 //load the memory addresses to be written to
407 MOV reg_gpio1_datain, GPIO1 | GPIO_CLEARDATAOUT //reg_gpio1_datain is now unused and is used here as a temp 404 MOV reg_gpio1_datain, GPIO1 | GPIO_CLEARDATAOUT //reg_gpio1_datain is now unused and is used here as a temp
408 MOV reg_gpio2_datain, GPIO2 | GPIO_CLEARDATAOUT //reg_gpio2_datain is now unused and is used here as a temp 405 MOV reg_gpio2_datain, GPIO2 | GPIO_CLEARDATAOUT //reg_gpio2_datain is now unused and is used here as a temp
409 //write 8 bytes for each GPIO 406 //write 8 bytes for each GPIO
410 //takes 30ns in total to go through the followint two lines 407 //takes 30ns in total to go through the following two lines
411 SBBO reg_gpio1_cleardataout, reg_gpio1_datain, 0, 8 // takes 145ns to be effective when going low, 185ns when going high 408 SBBO reg_gpio1_cleardataout, reg_gpio1_datain, 0, 8 // takes 145ns to be effective when going low, 185ns when going high
412 SBBO reg_gpio2_cleardataout, reg_gpio2_datain, 0, 8 //takes 95ns to be effective when going low, 130ns when going high 409 SBBO reg_gpio2_cleardataout, reg_gpio2_datain, 0, 8 //takes 95ns to be effective when going low, 130ns when going high
413 //reversing the order of the two lines above will swap the performances between the GPIO modules 410 //reversing the order of the two lines above will swap the performances between the GPIO modules
414 //i.e.: the first line will always take 145ns/185ns and the second one will always take 95ns/130ns, 411 //i.e.: the first line will always take 145ns/185ns and the second one will always take 95ns/130ns,
415 //regardless of whether the order is gpio1-gpio2 or gpio2-gpio1 412 //regardless of whether the order is gpio1-gpio2 or gpio2-gpio1
569 AND r28, r28, r27 566 AND r28, r28, r27
570 QBEQ POLL, r28, 0 567 QBEQ POLL, r28, 0
571 .endm 568 .endm
572 569
573 START: 570 START:
574 MOV r30, 0
575 // Set up c24 and c25 offsets with CTBIR register 571 // Set up c24 and c25 offsets with CTBIR register
576 // Thus C24 points to start of PRU0 RAM 572 // Thus C24 points to start of PRU0 RAM
577 MOV r3, 0x22020 // CTBIR0 573 MOV r3, 0x22020 // CTBIR0
578 MOV r2, 0 574 MOV r2, 0
579 SBBO r2, r3, 0, 4 575 SBBO r2, r3, 0, 4
782 MCASP_REG_READ_EXT MCASP_RBUF, r2 778 MCASP_REG_READ_EXT MCASP_RBUF, r2
783 779
784 WRITE_ONE_BUFFER: 780 WRITE_ONE_BUFFER:
785 // Write a single buffer of DAC samples and read a buffer of ADC samples 781 // Write a single buffer of DAC samples and read a buffer of ADC samples
786 // Load starting positions 782 // Load starting positions
787 SET r30.t15
788 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer 783 MOV reg_dac_current, reg_dac_buf0 // DAC: reg_dac_current is current pointer
789 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels 784 LMBD r2, reg_num_channels, 1 // 1, 2 or 3 for 2, 4 or 8 channels
790 LSL reg_adc_current, reg_frame_total, r2 785 LSL reg_adc_current, reg_frame_total, r2
791 LSL reg_adc_current, reg_adc_current, 2 // N * 2 * 2 * bufsize 786 LSL reg_adc_current, reg_adc_current, 2 // N * 2 * 2 * bufsize
792 ADD reg_adc_current, reg_adc_current, reg_dac_current // ADC: starts N * 2 * 2 * bufsize beyond DAC 787 ADD reg_adc_current, reg_adc_current, reg_dac_current // ADC: starts N * 2 * 2 * bufsize beyond DAC
803 MOV r2, MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately 798 MOV r2, MEM_DIGITAL_BUFFER1_OFFSET //so adjust offset appropriately
804 DIGITAL_BASE_CHECK_DONE: 799 DIGITAL_BASE_CHECK_DONE:
805 MOV reg_digital_current, MEM_DIGITAL_BASE 800 MOV reg_digital_current, MEM_DIGITAL_BASE
806 ADD reg_digital_current, reg_digital_current, r2 801 ADD reg_digital_current, reg_digital_current, r2
807 802
808 CLR r30.t15
809 WRITE_LOOP: 803 WRITE_LOOP:
810 // Write N channels to DAC from successive values in memory 804 // Write N channels to DAC from successive values in memory
811 // At the same time, read N channels from ADC 805 // At the same time, read N channels from ADC
812 // Unrolled by a factor of 2 to get high and low words 806 // Unrolled by a factor of 2 to get high and low words
813 MOV r1, 0 807 MOV r1, 0
882 // Now store the result and increment the pointer 876 // Now store the result and increment the pointer
883 SBCO reg_mcasp_adc_data, C_MCASP_MEM, reg_mcasp_adc_current, 4 877 SBCO reg_mcasp_adc_data, C_MCASP_MEM, reg_mcasp_adc_current, 4
884 ADD reg_mcasp_adc_current, reg_mcasp_adc_current, 4 878 ADD reg_mcasp_adc_current, reg_mcasp_adc_current, 4
885 MCASP_ADC_DONE: 879 MCASP_ADC_DONE:
886 QBBC SPI_SKIP_WRITE, reg_flags, FLAG_BIT_USE_SPI 880 QBBC SPI_SKIP_WRITE, reg_flags, FLAG_BIT_USE_SPI
887 881
888 // DAC: transmit low word (first in little endian) 882 // DAC: transmit low word (first in little endian)
889 MOV r2, 0xFFFF 883 MOV r2, 0xFFFF
890 AND r7, reg_dac_data, r2 884 AND r7, reg_dac_data, r2
891 LSL r7, r7, AD5668_DATA_OFFSET 885 LSL r7, r7, AD5668_DATA_OFFSET
892 MOV r8, (0x03 << AD5668_COMMAND_OFFSET) 886 MOV r8, (0x03 << AD5668_COMMAND_OFFSET)
950 // Repeat 4 times for 8 channels (2 samples per loop, r1 += 1 already happened) 944 // Repeat 4 times for 8 channels (2 samples per loop, r1 += 1 already happened)
951 // For 4 or 2 channels, repeat 2 or 1 times, according to flags 945 // For 4 or 2 channels, repeat 2 or 1 times, according to flags
952 ADD r1, r1, 1 946 ADD r1, r1, 1
953 QBNE ADC_DAC_LOOP, r1, reg_num_channels 947 QBNE ADC_DAC_LOOP, r1, reg_num_channels
954 QBA ADC_DAC_LOOP_DONE 948 QBA ADC_DAC_LOOP_DONE
955
956 SPI_SKIP_WRITE: 949 SPI_SKIP_WRITE:
957 // We get here only if the SPI ADC and DAC are disabled 950 // We get here only if the SPI ADC and DAC are disabled
958 // Just keep the loop going for McASP 951 // Just keep the loop going for McASP
959 952
960 // Toggle the high/low word for McASP control (since we send one word out of 953 // Toggle the high/low word for McASP control (since we send one word out of
1004 LBBO r2, reg_comm_addr, COMM_LED_PIN_MASK, 4 997 LBBO r2, reg_comm_addr, COMM_LED_PIN_MASK, 4
1005 MOV r1, GPIO_CLEARDATAOUT 998 MOV r1, GPIO_CLEARDATAOUT
1006 ADD r3, r3, r1 // Address for GPIO clear register 999 ADD r3, r3, r1 // Address for GPIO clear register
1007 SBBO r2, r3, 0, 4 // Clear GPIO pin 1000 SBBO r2, r3, 0, 4 // Clear GPIO pin
1008 LED_BLINK_DONE: 1001 LED_BLINK_DONE:
1009
1010 // Check if we should finish: flag is zero as long as it should run 1002 // Check if we should finish: flag is zero as long as it should run
1011 LBBO r2, reg_comm_addr, COMM_SHOULD_STOP, 4 1003 LBBO r2, reg_comm_addr, COMM_SHOULD_STOP, 4
1012 QBEQ WRITE_ONE_BUFFER, r2, 0 1004 QBEQ WRITE_ONE_BUFFER, r2, 0
1013 1005
1014 CLEANUP: 1006 CLEANUP:
1026 MOV r3, SPI_BASE + SPI_CH0CTRL 1018 MOV r3, SPI_BASE + SPI_CH0CTRL
1027 LBBO r2, r3, 0, 4 1019 LBBO r2, r3, 0, 4
1028 CLR r2, r2, 1 1020 CLR r2, r2, 1
1029 SBBO r2, r3, 0, 4 1021 SBBO r2, r3, 0, 4
1030 SPI_CLEANUP_DONE: 1022 SPI_CLEANUP_DONE:
1031
1032 // Signal the ARM that we have finished 1023 // Signal the ARM that we have finished
1033 MOV R31.b0, PRU0_ARM_INTERRUPT + 16 1024 MOV R31.b0, PRU0_ARM_INTERRUPT + 16
1034 HALT 1025 HALT