Parallel bus (address 8 bit, data 8 bit) access sample using GPIO pins.
Dependents: mini_board_PCU9669_demo mini_board_PCU9669
Parallel bus emulation sample code
mbed (LPC1768) does not have parallel bus but it can be emulated by GPIO.
Please find a notebook page for more infomation.
hardware_abs.c@6:3f4c439ea51b, 2012-08-28 (annotated)
- Committer:
- nxp_ip
- Date:
- Tue Aug 28 00:51:36 2012 +0000
- Revision:
- 6:3f4c439ea51b
- Parent:
- 5:8b54fb7ecfff
parallel bus read pulse width adjust (for non-burst read also)
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
nxp_ip | 0:d6ec2b9171cb | 1 | |
nxp_ip | 0:d6ec2b9171cb | 2 | /** A sample code for "mini board PCU9669/PCA9665" |
nxp_ip | 0:d6ec2b9171cb | 3 | * |
nxp_ip | 0:d6ec2b9171cb | 4 | * @author Akifumi (Tedd) OKANO, NXP Semiconductors |
nxp_ip | 1:5526d3e04b7a | 5 | * @version 1.1 |
nxp_ip | 1:5526d3e04b7a | 6 | * @date 11-Jul-2012 |
nxp_ip | 0:d6ec2b9171cb | 7 | * |
nxp_ip | 2:8f5c7901d52a | 8 | * ** Parallel bus accessing library version 2.0 (12-Jul-2012) |
nxp_ip | 0:d6ec2b9171cb | 9 | * ** version 2.0 has been made for speed optimization by register level control |
nxp_ip | 3:a3e71822a7a3 | 10 | * ** And it makes parallel bus speed independent from mbed-library (PortOut, PortInOut) |
nxp_ip | 0:d6ec2b9171cb | 11 | * |
nxp_ip | 0:d6ec2b9171cb | 12 | * Released under the MIT License: http://mbed.org/license/mit |
nxp_ip | 0:d6ec2b9171cb | 13 | * |
nxp_ip | 0:d6ec2b9171cb | 14 | * An operation sample of PCU9669/PCA9665 I2C bus controller. |
nxp_ip | 0:d6ec2b9171cb | 15 | * The mbed accesses the bus controller's parallel port (8/2 bit address and 8 bit data) by bit-banging. |
nxp_ip | 0:d6ec2b9171cb | 16 | * The bit-banging is poerformed by PortInOut function of mbed library. |
nxp_ip | 0:d6ec2b9171cb | 17 | * |
nxp_ip | 0:d6ec2b9171cb | 18 | * To make the code porting easier, all codes are partitioned into layers to abstract other parts. |
nxp_ip | 0:d6ec2b9171cb | 19 | * The mbed specific parts are concentrated in lowest layer: "hardware_abs.*". |
nxp_ip | 0:d6ec2b9171cb | 20 | * This module may need to be modified for the porting. |
nxp_ip | 0:d6ec2b9171cb | 21 | * |
nxp_ip | 0:d6ec2b9171cb | 22 | * All other upper layers are writen in standard-C. |
nxp_ip | 0:d6ec2b9171cb | 23 | * |
nxp_ip | 0:d6ec2b9171cb | 24 | * base code is written from 05-Sep-2011 to 09-Sep-2011. |
nxp_ip | 0:d6ec2b9171cb | 25 | * And demo code has been build on 11-Sep-2011. |
nxp_ip | 0:d6ec2b9171cb | 26 | * Debug and code adjustment has been done on 08-Sep-2011. |
nxp_ip | 0:d6ec2b9171cb | 27 | * Small sanitization for main.cpp. All mbed related codes are moved in to "hardware_abs.*". 13-Oct-2011 |
nxp_ip | 0:d6ec2b9171cb | 28 | * hardware_abs are moved into parallel_bus library folder, 3 LED driver operation sample 13-Feb.-2012 |
nxp_ip | 0:d6ec2b9171cb | 29 | * PCU9669 and PCA9665 codes are packed in a project 14-Feb-2012. |
nxp_ip | 0:d6ec2b9171cb | 30 | * |
nxp_ip | 0:d6ec2b9171cb | 31 | * Before builidng the code, please edit the file mini_board_PCU9669/config.h |
nxp_ip | 0:d6ec2b9171cb | 32 | * Un-comment the target name what you want to target. |
nxp_ip | 0:d6ec2b9171cb | 33 | */ |
nxp_ip | 0:d6ec2b9171cb | 34 | |
nxp_ip | 0:d6ec2b9171cb | 35 | /* |
nxp_ip | 0:d6ec2b9171cb | 36 | * "hardware_abs" module has been made to abstract hardware: Hardware abstract layer |
nxp_ip | 0:d6ec2b9171cb | 37 | * This is file which will be modified when the porting done for other MCUs. |
nxp_ip | 0:d6ec2b9171cb | 38 | */ |
nxp_ip | 0:d6ec2b9171cb | 39 | |
nxp_ip | 0:d6ec2b9171cb | 40 | /* |
nxp_ip | 0:d6ec2b9171cb | 41 | * This sample code has been made for mbed. The code emulates parallel SRAM bus using the mbed's GPIO ports. |
nxp_ip | 0:d6ec2b9171cb | 42 | * To maximize the port access speed, PortOut and PortInOut libraly used. |
nxp_ip | 0:d6ec2b9171cb | 43 | */ |
nxp_ip | 0:d6ec2b9171cb | 44 | |
nxp_ip | 0:d6ec2b9171cb | 45 | #include "mbed.h" |
nxp_ip | 0:d6ec2b9171cb | 46 | #include "hardware_abs.h" |
nxp_ip | 0:d6ec2b9171cb | 47 | |
nxp_ip | 0:d6ec2b9171cb | 48 | void register_check( LPC_GPIO_TypeDef *p ) { |
nxp_ip | 0:d6ec2b9171cb | 49 | printf( "%p\r\n", p ); |
nxp_ip | 0:d6ec2b9171cb | 50 | printf( " %p->FIODIR 0x%08X\r\n", p, p->FIODIR ); |
nxp_ip | 0:d6ec2b9171cb | 51 | printf( " %p->FIOMASK 0x%08X\r\n", p, p->FIOMASK ); |
nxp_ip | 0:d6ec2b9171cb | 52 | printf( " %p->FIOPIN 0x%08X\r\n", p, p->FIOPIN ); |
nxp_ip | 0:d6ec2b9171cb | 53 | printf( " %p->FIOSET 0x%08X\r\n", p, p->FIOSET ); |
nxp_ip | 0:d6ec2b9171cb | 54 | printf( " %p->FIOCLR 0x%08X\r\n", p, p->FIOCLR ); |
nxp_ip | 0:d6ec2b9171cb | 55 | } |
nxp_ip | 0:d6ec2b9171cb | 56 | |
nxp_ip | 0:d6ec2b9171cb | 57 | // GPIO port setting |
nxp_ip | 0:d6ec2b9171cb | 58 | |
nxp_ip | 0:d6ec2b9171cb | 59 | #define ADDR_MASK 0x07878000 // 8 bit address mask on PORT0: Address value will be set into this bit position |
nxp_ip | 0:d6ec2b9171cb | 60 | #define DATA_MASK 0x00000FF0 // 8 bit data mask on PORT0: Data value will be appeared on this bit position |
nxp_ip | 0:d6ec2b9171cb | 61 | #define CONTROL_MASK 0x00000038 // Control signals CS=bit5(pin21), WR=bit4(pin22), RD=bit3(pin23) |
nxp_ip | 0:d6ec2b9171cb | 62 | |
nxp_ip | 0:d6ec2b9171cb | 63 | PortOut addr_port( Port0, ADDR_MASK ); |
nxp_ip | 0:d6ec2b9171cb | 64 | PortInOut data_port( Port0, DATA_MASK ); |
nxp_ip | 0:d6ec2b9171cb | 65 | PortOut ctrl_port( Port2, CONTROL_MASK ); |
nxp_ip | 0:d6ec2b9171cb | 66 | InterruptIn int_port( p26 ); |
nxp_ip | 0:d6ec2b9171cb | 67 | |
nxp_ip | 0:d6ec2b9171cb | 68 | // The very early version of PCU9669 mini board has different configuration. |
nxp_ip | 0:d6ec2b9171cb | 69 | // Following part switches the port configuration for those board versions. |
nxp_ip | 0:d6ec2b9171cb | 70 | |
nxp_ip | 0:d6ec2b9171cb | 71 | //#define PROTOTYPE_BREADBOARD |
nxp_ip | 0:d6ec2b9171cb | 72 | |
nxp_ip | 0:d6ec2b9171cb | 73 | DigitalInOut reset_port( p20 ); |
nxp_ip | 0:d6ec2b9171cb | 74 | //DigitalOut trig_port( p19 ); |
nxp_ip | 0:d6ec2b9171cb | 75 | |
nxp_ip | 0:d6ec2b9171cb | 76 | // Next two macros defines interface for temporaly interrupt disable/enable functions. |
nxp_ip | 0:d6ec2b9171cb | 77 | // These macros are used to blocking interrupt until a bus access cycle completed. |
nxp_ip | 0:d6ec2b9171cb | 78 | // Because if the interrupt happened in a cycle, the emulated parallel port state will be disturbed. |
nxp_ip | 0:d6ec2b9171cb | 79 | // For the mbed, library routine: __disable_irq() / __enable_irq() can be used. |
nxp_ip | 0:d6ec2b9171cb | 80 | |
nxp_ip | 0:d6ec2b9171cb | 81 | #define interrupt_enable() __enable_irq() |
nxp_ip | 0:d6ec2b9171cb | 82 | #define interrupt_disable() __disable_irq() |
nxp_ip | 0:d6ec2b9171cb | 83 | |
nxp_ip | 0:d6ec2b9171cb | 84 | // "prev_access_was_write" is a variable to keep the previous data directions. |
nxp_ip | 0:d6ec2b9171cb | 85 | // Using this flag, successive write and read addess overhead can be reduced. |
nxp_ip | 0:d6ec2b9171cb | 86 | // This mechanism will not be required if the MCU has parallel port |
nxp_ip | 0:d6ec2b9171cb | 87 | |
nxp_ip | 0:d6ec2b9171cb | 88 | char prev_access_was_write; |
nxp_ip | 0:d6ec2b9171cb | 89 | |
nxp_ip | 0:d6ec2b9171cb | 90 | // ISR routine installer |
nxp_ip | 0:d6ec2b9171cb | 91 | |
nxp_ip | 0:d6ec2b9171cb | 92 | void install_ISR( void (*fptr)(void) ) { |
nxp_ip | 0:d6ec2b9171cb | 93 | int_port.fall( fptr ); |
nxp_ip | 0:d6ec2b9171cb | 94 | } |
nxp_ip | 0:d6ec2b9171cb | 95 | |
nxp_ip | 0:d6ec2b9171cb | 96 | // Hardware initialize: it defines initial state of the (emulated) parallel bus |
nxp_ip | 0:d6ec2b9171cb | 97 | |
nxp_ip | 0:d6ec2b9171cb | 98 | void hardware_initialize( void ) { |
nxp_ip | 0:d6ec2b9171cb | 99 | prev_access_was_write = 0; |
nxp_ip | 0:d6ec2b9171cb | 100 | ctrl_port = 0x38; // CS, WR and RD are deaserted (HIGH) |
nxp_ip | 0:d6ec2b9171cb | 101 | data_port.input(); // data bus set to Hi-Z |
nxp_ip | 0:d6ec2b9171cb | 102 | reset_port.output(); |
nxp_ip | 0:d6ec2b9171cb | 103 | reset_port.mode( PullUp ); |
nxp_ip | 0:d6ec2b9171cb | 104 | } |
nxp_ip | 0:d6ec2b9171cb | 105 | |
nxp_ip | 0:d6ec2b9171cb | 106 | // Hardware reset for PCU9669: It asserts RESET signal for 4us and waits 650us after deassert (reset recovery time) |
nxp_ip | 0:d6ec2b9171cb | 107 | |
nxp_ip | 0:d6ec2b9171cb | 108 | void reset( int reset_pulse_width_us, int reset_recovery_us ) { |
nxp_ip | 0:d6ec2b9171cb | 109 | hardware_reset( ASSERT ); // Minimum pulse width is 4us for PCU9669 |
nxp_ip | 0:d6ec2b9171cb | 110 | hw_wait_us( reset_pulse_width_us ); |
nxp_ip | 0:d6ec2b9171cb | 111 | hardware_reset( DEASSERT ); // deassert hardware /RESET sgnal |
nxp_ip | 0:d6ec2b9171cb | 112 | hw_wait_us( reset_recovery_us ); |
nxp_ip | 0:d6ec2b9171cb | 113 | } |
nxp_ip | 0:d6ec2b9171cb | 114 | |
nxp_ip | 0:d6ec2b9171cb | 115 | // Interface to Control hardware RESET signal |
nxp_ip | 0:d6ec2b9171cb | 116 | |
nxp_ip | 0:d6ec2b9171cb | 117 | void hardware_reset( char signal ) { |
nxp_ip | 0:d6ec2b9171cb | 118 | reset_port = signal; |
nxp_ip | 0:d6ec2b9171cb | 119 | } |
nxp_ip | 0:d6ec2b9171cb | 120 | |
nxp_ip | 0:d6ec2b9171cb | 121 | // Interface to Control hardware TRIGGER signal |
nxp_ip | 0:d6ec2b9171cb | 122 | |
nxp_ip | 0:d6ec2b9171cb | 123 | void hardware_trigger( char signal ) { |
nxp_ip | 0:d6ec2b9171cb | 124 | // trig_port = signal; |
nxp_ip | 0:d6ec2b9171cb | 125 | } |
nxp_ip | 0:d6ec2b9171cb | 126 | |
nxp_ip | 0:d6ec2b9171cb | 127 | // Single write cycle on (emulated) parallel bus |
nxp_ip | 0:d6ec2b9171cb | 128 | |
nxp_ip | 0:d6ec2b9171cb | 129 | void write_data( char addr, char data ) { |
nxp_ip | 0:d6ec2b9171cb | 130 | unsigned long addr_data; |
nxp_ip | 0:d6ec2b9171cb | 131 | |
nxp_ip | 0:d6ec2b9171cb | 132 | interrupt_disable(); // disable interrupt first |
nxp_ip | 0:d6ec2b9171cb | 133 | |
nxp_ip | 0:d6ec2b9171cb | 134 | addr_data = (addr << 19) | (addr << 15) | (data << 4); |
nxp_ip | 0:d6ec2b9171cb | 135 | |
nxp_ip | 0:d6ec2b9171cb | 136 | LPC_GPIO0->FIOMASK = ~(ADDR_MASK | DATA_MASK); |
nxp_ip | 0:d6ec2b9171cb | 137 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 138 | LPC_GPIO0->FIOSET = addr_data; |
nxp_ip | 0:d6ec2b9171cb | 139 | LPC_GPIO0->FIOCLR = ~addr_data; |
nxp_ip | 0:d6ec2b9171cb | 140 | |
nxp_ip | 0:d6ec2b9171cb | 141 | LPC_GPIO2->FIOCLR = 0x20; // Assert CS signal |
nxp_ip | 0:d6ec2b9171cb | 142 | |
nxp_ip | 0:d6ec2b9171cb | 143 | LPC_GPIO0->FIODIR = ADDR_MASK | DATA_MASK; |
nxp_ip | 0:d6ec2b9171cb | 144 | |
nxp_ip | 0:d6ec2b9171cb | 145 | LPC_GPIO2->FIOCLR = 0x30; // repeating register write to keep pulse width wide :) |
nxp_ip | 0:d6ec2b9171cb | 146 | |
nxp_ip | 0:d6ec2b9171cb | 147 | LPC_GPIO0->FIOSET = addr_data; |
nxp_ip | 0:d6ec2b9171cb | 148 | LPC_GPIO0->FIOCLR = ~addr_data; |
nxp_ip | 0:d6ec2b9171cb | 149 | |
nxp_ip | 0:d6ec2b9171cb | 150 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 151 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 152 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 153 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 154 | LPC_GPIO2->FIOSET = 0x38; |
nxp_ip | 0:d6ec2b9171cb | 155 | |
nxp_ip | 0:d6ec2b9171cb | 156 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 157 | |
nxp_ip | 0:d6ec2b9171cb | 158 | interrupt_enable(); // enable interrupt again |
nxp_ip | 0:d6ec2b9171cb | 159 | } |
nxp_ip | 0:d6ec2b9171cb | 160 | |
nxp_ip | 0:d6ec2b9171cb | 161 | |
nxp_ip | 0:d6ec2b9171cb | 162 | char read_data( char addr ) { |
nxp_ip | 0:d6ec2b9171cb | 163 | unsigned long addr_data; |
nxp_ip | 0:d6ec2b9171cb | 164 | volatile char tmp; |
nxp_ip | 0:d6ec2b9171cb | 165 | |
nxp_ip | 0:d6ec2b9171cb | 166 | interrupt_disable(); // disable interrupt first |
nxp_ip | 0:d6ec2b9171cb | 167 | |
nxp_ip | 0:d6ec2b9171cb | 168 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 169 | |
nxp_ip | 0:d6ec2b9171cb | 170 | LPC_GPIO0->FIOMASK = ~ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 171 | addr_data = (addr << 19) | (addr << 15); |
nxp_ip | 0:d6ec2b9171cb | 172 | LPC_GPIO0->FIOSET = addr_data; |
nxp_ip | 0:d6ec2b9171cb | 173 | LPC_GPIO0->FIOCLR = ~addr_data; |
nxp_ip | 0:d6ec2b9171cb | 174 | |
nxp_ip | 0:d6ec2b9171cb | 175 | LPC_GPIO2->FIOCLR = 0x28; // Assert CS and RD signals |
nxp_ip | 0:d6ec2b9171cb | 176 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 177 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 178 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 6:3f4c439ea51b | 179 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 6:3f4c439ea51b | 180 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 181 | |
nxp_ip | 0:d6ec2b9171cb | 182 | LPC_GPIO0->FIOMASK = ~DATA_MASK; |
nxp_ip | 0:d6ec2b9171cb | 183 | tmp = (LPC_GPIO0->FIOPIN >> 4) & 0xFF; // Read data bus into var |
nxp_ip | 0:d6ec2b9171cb | 184 | |
nxp_ip | 0:d6ec2b9171cb | 185 | LPC_GPIO2->FIOSET = 0x38; |
nxp_ip | 0:d6ec2b9171cb | 186 | |
nxp_ip | 0:d6ec2b9171cb | 187 | interrupt_enable(); // enable interrupt again |
nxp_ip | 0:d6ec2b9171cb | 188 | |
nxp_ip | 0:d6ec2b9171cb | 189 | return ( tmp ); |
nxp_ip | 0:d6ec2b9171cb | 190 | } |
nxp_ip | 0:d6ec2b9171cb | 191 | |
nxp_ip | 0:d6ec2b9171cb | 192 | // Wait for micro-seconds |
nxp_ip | 0:d6ec2b9171cb | 193 | |
nxp_ip | 0:d6ec2b9171cb | 194 | void hw_wait_us( int v ) { |
nxp_ip | 0:d6ec2b9171cb | 195 | wait_us( v ); |
nxp_ip | 0:d6ec2b9171cb | 196 | } |
nxp_ip | 0:d6ec2b9171cb | 197 | |
nxp_ip | 0:d6ec2b9171cb | 198 | // Wait for seconds |
nxp_ip | 0:d6ec2b9171cb | 199 | |
nxp_ip | 0:d6ec2b9171cb | 200 | void wait_sec( float f ) { |
nxp_ip | 0:d6ec2b9171cb | 201 | wait( f ); |
nxp_ip | 0:d6ec2b9171cb | 202 | } |
nxp_ip | 0:d6ec2b9171cb | 203 | |
nxp_ip | 0:d6ec2b9171cb | 204 | // Following part is an optionto accerelate bus access. |
nxp_ip | 0:d6ec2b9171cb | 205 | // If such trick is not required, undefine the "BURST_DATA_ACCESS" and don't touch it. |
nxp_ip | 0:d6ec2b9171cb | 206 | // |
nxp_ip | 0:d6ec2b9171cb | 207 | // Next two functions access single address with repeating read/write. |
nxp_ip | 0:d6ec2b9171cb | 208 | // The repeating read/write are used often for PCU9669 like SLATABLE, TRANCONFIG and DATA (buffer accesses). |
nxp_ip | 0:d6ec2b9171cb | 209 | // So this accerelation contributes saving MCU time. |
nxp_ip | 0:d6ec2b9171cb | 210 | // |
nxp_ip | 0:d6ec2b9171cb | 211 | // For the porting, it may be good idea to modify those routines to DMA access. |
nxp_ip | 0:d6ec2b9171cb | 212 | |
nxp_ip | 0:d6ec2b9171cb | 213 | #ifdef BURST_DATA_ACCESS |
nxp_ip | 0:d6ec2b9171cb | 214 | |
nxp_ip | 0:d6ec2b9171cb | 215 | void write_data_burst( char addr, char *data, char length ) { |
nxp_ip | 0:d6ec2b9171cb | 216 | unsigned long addr_data; |
nxp_ip | 0:d6ec2b9171cb | 217 | int i; |
nxp_ip | 0:d6ec2b9171cb | 218 | |
nxp_ip | 0:d6ec2b9171cb | 219 | interrupt_disable(); // disable interrupt first |
nxp_ip | 0:d6ec2b9171cb | 220 | |
nxp_ip | 0:d6ec2b9171cb | 221 | addr_data = (addr << 19) | (addr << 15); |
nxp_ip | 0:d6ec2b9171cb | 222 | |
nxp_ip | 0:d6ec2b9171cb | 223 | LPC_GPIO0->FIOMASK = ~ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 224 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 225 | LPC_GPIO0->FIOSET = addr_data; |
nxp_ip | 0:d6ec2b9171cb | 226 | LPC_GPIO0->FIOCLR = ~addr_data; |
nxp_ip | 0:d6ec2b9171cb | 227 | |
nxp_ip | 0:d6ec2b9171cb | 228 | LPC_GPIO2->FIOCLR = 0x20; // Assert CS signal |
nxp_ip | 0:d6ec2b9171cb | 229 | |
nxp_ip | 0:d6ec2b9171cb | 230 | LPC_GPIO0->FIODIR = ADDR_MASK | DATA_MASK; |
nxp_ip | 0:d6ec2b9171cb | 231 | LPC_GPIO0->FIOMASK = ~DATA_MASK; |
nxp_ip | 0:d6ec2b9171cb | 232 | |
nxp_ip | 0:d6ec2b9171cb | 233 | for ( i = 0; i < length; i++ ) { // repeat data read access |
nxp_ip | 0:d6ec2b9171cb | 234 | |
nxp_ip | 0:d6ec2b9171cb | 235 | addr_data = *(data + i) << 4; |
nxp_ip | 0:d6ec2b9171cb | 236 | |
nxp_ip | 0:d6ec2b9171cb | 237 | LPC_GPIO2->FIOCLR = 0x30; // repeating register write to keep pulse width wide :) |
nxp_ip | 0:d6ec2b9171cb | 238 | |
nxp_ip | 0:d6ec2b9171cb | 239 | LPC_GPIO0->FIOCLR = ~addr_data; |
nxp_ip | 0:d6ec2b9171cb | 240 | LPC_GPIO0->FIOSET = addr_data; |
nxp_ip | 0:d6ec2b9171cb | 241 | |
nxp_ip | 0:d6ec2b9171cb | 242 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 243 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 244 | LPC_GPIO2->FIOCLR = 0x30; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 245 | LPC_GPIO2->FIOSET = 0x10; |
nxp_ip | 0:d6ec2b9171cb | 246 | } |
nxp_ip | 0:d6ec2b9171cb | 247 | LPC_GPIO2->FIOSET = 0x38; |
nxp_ip | 0:d6ec2b9171cb | 248 | |
nxp_ip | 0:d6ec2b9171cb | 249 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 250 | interrupt_enable(); // enable interrupt again |
nxp_ip | 0:d6ec2b9171cb | 251 | } |
nxp_ip | 0:d6ec2b9171cb | 252 | |
nxp_ip | 0:d6ec2b9171cb | 253 | void read_data_burst( char addr, char *data, char length ) { |
nxp_ip | 0:d6ec2b9171cb | 254 | unsigned long addr_data; |
nxp_ip | 0:d6ec2b9171cb | 255 | int i; |
nxp_ip | 0:d6ec2b9171cb | 256 | |
nxp_ip | 0:d6ec2b9171cb | 257 | interrupt_disable(); // disable interrupt first |
nxp_ip | 0:d6ec2b9171cb | 258 | |
nxp_ip | 0:d6ec2b9171cb | 259 | addr_data = (addr << 19) | (addr << 15); |
nxp_ip | 0:d6ec2b9171cb | 260 | |
nxp_ip | 0:d6ec2b9171cb | 261 | LPC_GPIO0->FIOMASK = ~ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 262 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 263 | LPC_GPIO0->FIOSET = addr_data; |
nxp_ip | 0:d6ec2b9171cb | 264 | LPC_GPIO0->FIOCLR = ~addr_data; |
nxp_ip | 0:d6ec2b9171cb | 265 | |
nxp_ip | 0:d6ec2b9171cb | 266 | LPC_GPIO0->FIOMASK = ~DATA_MASK; |
nxp_ip | 0:d6ec2b9171cb | 267 | |
nxp_ip | 0:d6ec2b9171cb | 268 | for ( i = 0; i < length; i++ ) { // repeat data read access |
nxp_ip | 0:d6ec2b9171cb | 269 | LPC_GPIO2->FIOCLR = 0x28; // Assert CS and RD signals |
nxp_ip | 0:d6ec2b9171cb | 270 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 271 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 272 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 5:8b54fb7ecfff | 273 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 5:8b54fb7ecfff | 274 | LPC_GPIO2->FIOCLR = 0x28; // to keep timing |
nxp_ip | 0:d6ec2b9171cb | 275 | |
nxp_ip | 0:d6ec2b9171cb | 276 | *(data + i) = (LPC_GPIO0->FIOPIN >> 4) & 0xFF; // Read data bus into var |
nxp_ip | 0:d6ec2b9171cb | 277 | LPC_GPIO2->FIOSET = 0x08; |
nxp_ip | 0:d6ec2b9171cb | 278 | } |
nxp_ip | 0:d6ec2b9171cb | 279 | LPC_GPIO2->FIOSET = 0x38; |
nxp_ip | 0:d6ec2b9171cb | 280 | |
nxp_ip | 0:d6ec2b9171cb | 281 | LPC_GPIO0->FIODIR = ADDR_MASK; |
nxp_ip | 0:d6ec2b9171cb | 282 | interrupt_enable(); // enable interrupt again |
nxp_ip | 0:d6ec2b9171cb | 283 | } |
nxp_ip | 0:d6ec2b9171cb | 284 | |
nxp_ip | 0:d6ec2b9171cb | 285 | #endif |
nxp_ip | 0:d6ec2b9171cb | 286 | |
nxp_ip | 0:d6ec2b9171cb | 287 |