I, partially, made it to work. Now I see activity in the pins but still the MAX7219 seems not to be receiving the data transmitted.
Below is the code that I have so far.
#define __SFR_OFFSET 0
#include <avr/io.h>
.global SPI_begin
.global SPI_setDataMode
.global SPI_transfer
.global SPI_end
.equ SPI_MODE1, 0x04
SPI_begin:
; Clear bits USISIE, USIOIE, and USIWM1 in USICR
in r16, _SFR_IO_ADDR(USICR)
cbr r16, (1 << USISIE) | (1 << USIOIE) | (1 << USIWM1)
out _SFR_IO_ADDR(USICR), r16
; Set bits USIWM0, USICS1, and USICLK in USICR
in r16, _SFR_IO_ADDR(USICR)
sbr r16, (1 << USIWM0) | (1 << USICS1) | (1 << USICLK)
out _SFR_IO_ADDR(USICR), r16
; Set PB2 (USCK) as output
sbi _SFR_IO_ADDR(DDRB), DDB2
; Set PB1 (DO/MOSI) as output
sbi _SFR_IO_ADDR(DDRB), DDB1
; Set PB0 (DI/MISO) as input
cbi _SFR_IO_ADDR(DDRB), DDB0
ret
SPI_setDataMode:
; Clear USICS0 bit to set SPI_MODE0 initially
in r16, _SFR_IO_ADDR(USICR)
cbr r16, (1 << USICS0)
cpi r24, SPI_MODE1 ; Check if the mode is SPI_MODE1
brne EndDataMode ; If not, jump to EndDataMode
; Set USICS0 bit for SPI_MODE1
sbr r16, (1 << USICS0)
EndDataMode:
out _SFR_IO_ADDR(USICR), r16
ret
SPI_transfer:
; Disable interrupts
cli
; Load data into USIDR
out _SFR_IO_ADDR(USIDR), r24
; Clear counter overflow interrupt flag
ldi r16, (1 << USIOIF)
out _SFR_IO_ADDR(USISR), r16
SPITransfer_loop:
; Toggle clock
sbi _SFR_IO_ADDR(USICR), USITC
; Check if USIOIF is set
in r16, _SFR_IO_ADDR(USISR)
sbrc r16, USIOIF
rjmp SPITransfer_loop
; Re-enable interrupts
sei
; Load received data
in r24, _SFR_IO_ADDR(USIDR)
ret
SPI_end:
; Clear USIWM1 and USIWM0 bits to disable USI
in r16, _SFR_IO_ADDR(USICR)
cbr r16, (1 << USIWM1) | (1 << USIWM0)
out _SFR_IO_ADDR(USICR), r16
ret
Still, if someone has any idea why my LED matrix is not working would be really appreciated.